public void PushContext(ServerContextBase context) { lock (updateLock) { if (context != null && !afterPushContexts.Contains(context)) { InitializeServerContext(context); afterPushContexts.Add(context); contextChains.Add(context, currentContext); } } }
private void UpdateImpl() { while (hostHandledData.Count > 0) { NetworkData networkData = null; lock (this) { networkData = hostHandledData.Dequeue(); } foreach (ServerContextBase context in contexts) { currentContext = context; context.Process(networkData); } if (networkData is AddUserNetworkData) { lock (userLastUpdatedAt) { userLastUpdatedAt[((AddUserNetworkData)networkData).Id] = DateTime.Now; } } else if (networkData is OldProtocolNetworkData) { host.Write(PPDPackV2DisconnectBytes, networkData.Id); if (!delayedDisconnects.ContainsKey(networkData.Id)) { delayedDisconnects.Add(networkData.Id, DateTime.Now); } } } foreach (ServerContextBase context in contexts) { currentContext = context; context.Update(); } foreach (ServerContextBase context in afterPushContexts) { contexts.Add(context); } foreach (ServerContextBase context in afterPopContexts) { contexts.Remove(context); if (contextChains.ContainsKey(context)) { ServerContextBase parent = contextChains[context]; parent.OnChildPoped(); contextChains.Remove(context); } } afterPopContexts.Clear(); afterPushContexts.Clear(); lock (userLastUpdatedAt) { var removeConnections = new List <ConnectionBase>(); var notExistUserIds = new List <int>(); foreach (var kvp in userLastUpdatedAt) { if (DateTime.Now - kvp.Value >= TimeSpan.FromMinutes(15)) { var connection = host.GetConnection(kvp.Key); if (connection != null) { hostHandledData.Enqueue(new DeleteUserNetworkData { Id = kvp.Key }); removeConnections.Add(connection); } else { notExistUserIds.Add(kvp.Key); } } } foreach (var userId in notExistUserIds) { userLastUpdatedAt.Remove(userId); } foreach (var connection in removeConnections) { host.Close(connection); } } lock (delayedDisconnects) { var removeConnections = new List <ConnectionBase>(); var notExistUserIds = new List <int>(); foreach (var kvp in delayedDisconnects) { if (DateTime.Now - kvp.Value >= TimeSpan.FromSeconds(1)) { var connection = host.GetConnection(kvp.Key); if (connection != null) { hostHandledData.Enqueue(new DeleteUserNetworkData { Id = kvp.Key }); removeConnections.Add(connection); } else { notExistUserIds.Add(kvp.Key); } } } foreach (var userId in notExistUserIds) { delayedDisconnects.Remove(userId); } foreach (var connection in removeConnections) { host.Close(connection); } } }
private void InitializeServerContext(ServerContextBase context) { context.ContextManager = this; context.Host = host; }
protected ServerContextBase(ServerContextBase previousContext) { processors = new Dictionary <Type, Tuple <object, MethodInfo> >(); }
public MainGameContext(ServerContextBase previousContext) : base(previousContext) { stopWatch = new Stopwatch(); userList = new List <UserInfo>(); userPlayStateList = new List <UserPlayState>(); foreach (UserInfo userInfo in (previousContext as MenuContext).UserList) { userList.Add(userInfo); userPlayStateList.Add(new UserPlayState { User = userInfo }); } resultList = new List <PPDMultiServer.Model.UserResult>(); stopWatch.Start(); waitStartTime = stopWatch.ElapsedMilliseconds; AddProcessor <MainGameLoadedNetworkData>(networkData => { var userPlayState = FindUserPlayState(networkData.Id); if (userPlayState != null) { Host.Write(MessagePackSerializer.Serialize(new MainGameLoadedNetworkData { Id = userPlayState.User.ID })); userPlayState.Loaded = true; waitStartTime = stopWatch.ElapsedMilliseconds; } }); AddProcessor <ChangeScoreNetworkData>(networkData => { var userPlayState = FindUserPlayState(networkData.Id); if (userPlayState != null) { userPlayState.Score = networkData.Score; Host.WriteExceptID(MessagePackSerializer.Serialize(new ChangeScoreNetworkData { Id = userPlayState.User.ID, Score = networkData.Score }), userPlayState.User.ID); } }); AddProcessor <ChangeLifeNetworkData>(networkData => { var userPlayState = FindUserPlayState(networkData.Id); if (userPlayState != null) { userPlayState.Life = networkData.Life; Host.WriteExceptID(MessagePackSerializer.Serialize(new ChangeLifeNetworkData { Id = userPlayState.User.ID, Life = networkData.Life }), userPlayState.User.ID); } }); AddProcessor <ChangeEvaluateNetworkData>(networkData => { var userPlayState = FindUserPlayState(networkData.Id); if (userPlayState != null) { userPlayState.Evaluate = networkData.Evaluate; Host.WriteExceptID(MessagePackSerializer.Serialize(new ChangeEvaluateNetworkData { Id = userPlayState.User.ID, Evaluate = networkData.Evaluate }), userPlayState.User.ID); } }); AddProcessor <SendResultNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null) { AddResult(networkData.Result, user); if (user.IsLeader) { if (state != State.WaitFinish) { state = State.WaitFinish; finishWaitStartTime = stopWatch.ElapsedMilliseconds; } } } }); AddProcessor <AddEffectToPlayerNetworkData>(networkData => { Host.Write(MessagePackSerializer.Serialize(new AddEffectToPlayerNetworkData { ItemType = networkData.ItemType, Id = networkData.Id }), networkData.UserId); if (ContextManager.Logger != null) { var user = FindUser(networkData.Id); var targetUser = FindUser(networkData.UserId); if (user != null && targetUser != null) { ContextManager.Logger.AddLog("{0}(@{1}) used {2} to {3}(@{4})", user.Name, user.AccountId, networkData.ItemType, targetUser.Name, targetUser.AccountId); } } }); AddProcessor <AddEffectNetworkData>(networkData => { Host.WriteExceptID(MessagePackSerializer.Serialize(new AddEffectToPlayerNetworkData { ItemType = networkData.ItemType, Id = networkData.Id }), networkData.Id); if (ContextManager.Logger != null) { var user = FindUser(networkData.Id); if (user != null) { ContextManager.Logger.AddLog("{0}(@{1}) used {2}", user.Name, user.AccountId, networkData.ItemType); } } }); AddProcessor <JustGoToMenuNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null && user.IsLeader) { Host.Write(MessagePackSerializer.Serialize(new JustGoToMenuNetworkData())); ContextManager.PopContext(); } }); AddProcessor <DeleteUserNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null) { DeleteUser(user); } }); }
public MenuContext(ServerContextBase previousContext, PPDServer server) : base(previousContext) { this.server = server; version = FileVersionInfo.GetVersionInfo(Assembly.GetAssembly(this.GetType()).Location).FileVersion; kickedIPs = new List <string>(); userList = new List <UserInfo>(); currentRule = new GameRule(); stopWatch = new Stopwatch(); stopWatch.Start(); AddProcessor <AddUserNetworkData>(networkData => { if (networkData.Version != version) { Host.Write(MessagePackSerializer.Serialize(new CloseConnectNetworkData { Reason = CloseConnectReason.VersionDifference }), networkData.Id); return; } else if (userList.Count == 16) { Host.Write(MessagePackSerializer.Serialize(new CloseConnectNetworkData { Reason = CloseConnectReason.MaximumCapacity }), networkData.Id); return; } else if (kickedIPs.Contains(networkData.Ip)) { Host.Write(MessagePackSerializer.Serialize(new CloseConnectNetworkData { Reason = CloseConnectReason.Kicked }), networkData.Id); return; } Host.Write(MessagePackSerializer.Serialize(new SendServerInfoNetworkData { Id = networkData.Id, AllowedModIds = server.AllowedModIds }), networkData.Id); if (currentSong != null) { Host.Write(MessagePackSerializer.Serialize(new ChangeSongNetworkData { Hash = currentSong.Hash, Difficulty = currentSong.Difficulty }), networkData.Id); } Host.Write(MessagePackSerializer.Serialize(new ChangeGameRuleNetworkData { GameRule = currentRule }), networkData.Id); foreach (UserInfo tempUser in userList) { Host.Write(MessagePackSerializer.Serialize(new AddUserNetworkData { Id = tempUser.ID, UserName = tempUser.Name, AccountId = tempUser.AccountId, State = tempUser.CurrentState, }), networkData.Id); } var user = AddUser((AddUserNetworkData)networkData); Host.WriteExceptID(MessagePackSerializer.Serialize(new AddUserNetworkData { Id = user.ID, UserName = user.Name, AccountId = user.AccountId, State = user.CurrentState, }), user.ID); Host.Write(MessagePackSerializer.Serialize(new ChangeLeaderNetworkData { UserId = Leader.ID }), user.ID); if (ContextManager.Logger != null) { ContextManager.Logger.AddLog(String.Format("{0}({1}) joined", user.Name, user.AccountId)); } }); AddProcessor <DeleteUserNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null) { DeleteUser(user); Host.Write(MessagePackSerializer.Serialize(new DeleteUserNetworkData { Id = user.ID })); SendCommonSongInfo(); if (ContextManager.Logger != null) { ContextManager.Logger.AddLog(String.Format("{0}({1}) leaved", user.Name, user.AccountId)); } } }); AddProcessor <AddMessageNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null) { Host.WriteExceptID(MessagePackSerializer.Serialize(new AddMessageNetworkData { Message = networkData.Message, Id = user.ID }), user.ID); if (ContextManager.Logger != null) { ContextManager.Logger.AddLog(String.Format("{0}({1}) said '{2}'", user.Name, user.AccountId, networkData.Message)); } } }); AddProcessor <AddPrivateMessageNetworkData>(networkData => { var user = FindUser(networkData.Id); var targetUser = FindUser(networkData.UserId); if (user != null && targetUser != null) { Host.Write(MessagePackSerializer.Serialize(new AddPrivateMessageNetworkData { Message = networkData.Message, Id = networkData.Id, UserId = networkData.UserId }), networkData.UserId); if (ContextManager.Logger != null) { ContextManager.Logger.AddLog(String.Format("{0}({1}) said to {2}({3}) '{4}'", user.Name, user.AccountId, targetUser.Name, targetUser.AccountId, networkData.Message)); } } }); AddProcessor <ChangeUserStateNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null) { user.CurrentState = networkData.State; Host.WriteExceptID(MessagePackSerializer.Serialize(new ChangeUserStateNetworkData { State = user.CurrentState, Id = user.ID }), user.ID); } }); AddProcessor <HasSongNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null) { user.HasSong = true; Host.WriteExceptID(MessagePackSerializer.Serialize(new HasSongNetworkData { Id = networkData.Id }), user.ID); } }); AddProcessor <FailedToCreateRoomNetworkData>(networkData => { ContextManager.OnFailedToCreateRoom(); if (ContextManager.Logger != null) { ContextManager.Logger.AddLog("Failed to create room"); } }); AddProcessor <ChangeGameRuleNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null && user.IsLeader) { if (state == State.None) { currentRule = networkData.GameRule; Host.Write(MessagePackSerializer.Serialize(new ChangeGameRuleNetworkData { GameRule = currentRule })); if (ContextManager.Logger != null) { ContextManager.Logger.AddLog(String.Format("Rule was changed to {0}", currentRule)); } } } }); AddProcessor <ChangeSongNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null && user.IsLeader) { if (state == State.None) { currentSong = new SongInfo { Hash = networkData.Hash, Difficulty = networkData.Difficulty }; foreach (var u in userList) { u.HasSong = false; } Host.Write(MessagePackSerializer.Serialize(new ChangeSongNetworkData { Hash = networkData.Hash, Difficulty = networkData.Difficulty })); if (ContextManager.Logger != null) { ContextManager.Logger.AddLog(String.Format("Song was changed {0}({1})", GetStringArray(currentSong.Hash), currentSong.Difficulty)); } } } }); AddProcessor <PingNetworkData>(networkData => { Host.Write(MessagePackSerializer.Serialize(new PingUserNetworkData { Ping = (int)(stopWatch.ElapsedMilliseconds - networkData.Time), Id = networkData.Id })); }); AddProcessor <ForceStartNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null && user.IsLeader) { forceStart = true; Host.Write(MessagePackSerializer.Serialize(new ForceStartNetworkData())); } }); AddProcessor <SendScoreListNetworkData>(networkData => { var user = FindUser(networkData.Id); if (user != null) { user.SongInfos = networkData.SongInfos; SendCommonSongInfo(); } }); AddProcessor <KickUserNetworkData>(networkData => { var user = FindUser(networkData.Id); var targetUser = FindUser(networkData.UserId); if (user != null && user.IsLeader && targetUser != null && targetUser != user) { kickedIPs.Add(targetUser.Ip); Host.Write(MessagePackSerializer.Serialize(new CloseConnectNetworkData { Reason = CloseConnectReason.Kicked }), targetUser.ID); Host.WriteExceptID(MessagePackSerializer.Serialize(new KickUserNetworkData { UserId = targetUser.ID }), targetUser.ID); DeleteUser(targetUser); SendCommonSongInfo(); if (ContextManager.Logger != null) { ContextManager.Logger.AddLog(String.Format("{0}({1}) was kicked", targetUser.Name, targetUser.AccountId)); } } }); AddProcessor <ChangeLeaderNetworkData>(networkData => { var user = FindUser(networkData.Id); var targetUser = FindUser(networkData.UserId); if (user != null && user.IsLeader && targetUser != null && targetUser != user) { Host.Write(MessagePackSerializer.Serialize(new ChangeLeaderNetworkData { UserId = targetUser.ID })); user.IsLeader = false; targetUser.IsLeader = true; if (ContextManager.Logger != null) { ContextManager.Logger.AddLog(String.Format("Leader was changed to {0}({1})", targetUser.Name, targetUser.AccountId)); } } }); }