Files
caliverse_server/GameServer/z.Backup/GameServer.cs
2025-05-01 07:20:41 +09:00

640 lines
26 KiB
C#

//using GameServer.World;
//using Nettention.Proud;
//using ServerCommon;
//using ServerCommon.Redis;
//using ServerCore; using ServerBase;
//using System.Diagnostics;
//using System.Net;
//using ControlCenter.NamedPipe;
//namespace GameServer
//{
// internal class GameServer
// {
// static public GameServer Instance { get; } = new();
// static public AtomicBool m_user_login_block_enable = new(false);
// public NetServer _srv { get; } = new();
// PClientToGame.Stub _stub = new();
// public PClientToGame.Proxy _proxy { get; } = new();
// CancellationTokenSource _cts = new();
// TaskCompletionSource<bool>? _runTask;
// public RabbitMQ4Game _rabbitMQ4Game = null!;
// public string ServerName { get; private set; } = string.Empty;
// public string WorldServerName { get; private set; } = string.Empty;
// public AwsNewInstanceInfo myServerInfo = new AwsNewInstanceInfo();
// List<Task> periodicTasks = new(10);
// List<ChannelInfo> ChannelInfoList = new(1000);
// public Map? Map;
// public ChatCommand ChatCommand { get; private set; } = new ChatCommand();
// private GameServer()
// {
//#pragma warning disable CS1998 // 이 비동기 메서드에는 'await' 연산자가 없으며 메서드가 동시에 실행됩니다.
// _srv.ClientJoinHandler = async (clientInfo) =>
// {
// using (clientInfo)
// {
// Log.getLogger().debug($"Client {clientInfo.hostID.ToString()} ip:{clientInfo.m_TcpLocalAddrFromServer.ToString()} connected.");
// ClientSession session = new ClientSession(clientInfo.hostID, "", "");
// ClientSessionManager.Instance.AddHost(session);
// NamedPipeClientHelper.Instance.SetCurrentClientConnection(true);
// }
// };
// // set a routine for client leave event.
// _srv.ClientLeaveHandler = async (clientInfo, errorInfo, comment) =>
// {
// using (clientInfo)
// {
// Log.getLogger().debug($"Client {clientInfo.hostID.ToString()} ip:{clientInfo.tcpAddrFromServer.IPToString()} disconnected.");
// NamedPipeClientHelper.Instance.SetCurrentClientConnection(false);
// ClientSession? client = ClientSessionManager.Instance.GetSession(clientInfo.hostID);
// if (client == null)
// {
// Log.getLogger().error($"Notfound Session hostId:{clientInfo.hostID}");
// return;
// }
// // 세션종료로 레디스에 지운 정보를 백그라운드에서 다시 등록하는 것을 방지하기 위해 먼저 뺀다.
// // Close시에 이미 세션매니저에서는 제거된 상태임을 주의 바람.
// _ = client._serializer.post(async () =>
// {
// ClientSessionManager.Instance.ReleaseSession(client);
// await client.Close();
// });
// }
// };
// _srv.ErrorHandler = (ErrorInfo Info) =>
// {
// using (Info)
// {
// Log.getLogger().error(Info.ToString());
// }
// };
// _srv.ExceptionHandler = (Exception ex) =>
// {
// Log.getLogger().error(ex.ToString());
// };
// _srv.WarningHandler = (ErrorInfo Info) =>
// {
// using (Info)
// {
// Log.getLogger().warn(Info.ToString());
// }
// };
// _srv.InformationHandler = (ErrorInfo Info) =>
// {
// using (Info)
// {
// Log.getLogger().info(Info.ToString());
// }
// };
// _srv.ClientHackSuspectedHandler = (HostID clientID, HackType hackType) =>
// {
// var clientInfo = _srv.GetClientInfo(clientID);
// using (clientInfo)
// {
// ClientSession? client = ClientSessionManager.Instance.GetSession(clientID);
// if (client != null)
// {
// Log.getLogger().error($"hostID:{clientID} HanckType:{hackType} {clientInfo.m_TcpLocalAddrFromServer.ToString()}, AccountID:{client.Id}");
// }
// else
// {
// Log.getLogger().error($"hostID:{clientID} HanckType:{hackType} {clientInfo.m_TcpLocalAddrFromServer.ToString()}");
// }
// }
// };
//#pragma warning restore CS1998 // 이 비동기 메서드에는 'await' 연산자가 없으며 메서드가 동시에 실행됩니다.
// }
// void InitStub()
// {
// _stub.Message = (HostID remote, RmiContext rmiContext, ClientToGame message) =>
// {
// _ = AuthHandler.ProcessRequestPacket(remote, rmiContext, message.Request);
// return true;
// };
// }
// public async Task<bool> StartServer(Options option)
// {
// //서버 중복시 종료
// if (ServerUtil.isExistProcess(Process.GetCurrentProcess().ProcessName + Convert.ToString(option.Port)))
// {
// Log.getLogger().error("Duplicate Port : " + Process.GetCurrentProcess().ProcessName + Convert.ToString(option.Port));
// return false;
// }
// InitStub();
// _srv.AttachStub(_stub);
// _srv.AttachProxy(_proxy);
// string ip = string.Empty;
// if (GameServerApp.Instance.Config.ServiceType == "Dev")
// {
// ip = ServerUtil.GetLocalIPv4();
// }
// else
// {
// ip = ServerUtil.GetPublicIPv4();
// }
// m_user_login_block_enable.set(GameServerApp.Instance.Config.AccountLoginBlockEnable);
// ServerType serverType = GameServerApp.Instance.Config.GameServerType == EGameServerType.Channel ? ServerType.Game : ServerType.Indun;
// myServerInfo.worldId = option.worldid;
// myServerInfo.channel = option.channel;
// myServerInfo.ip = ip;
// myServerInfo.port = option.Port;
// myServerInfo.serverType = (int)serverType;
// myServerInfo.capacity = GameServerApp.Instance.Config.DefaultMaxUser;
// Constant.g_MaxUser = GameServerApp.Instance.Config.DefaultMaxUser;
// if (GameServerApp.Instance.Config.AWS.Enable)
// {
// myServerInfo.instanceId = await ServerUtil.GetAwsInstanceID();
// }
// if (GameServerApp.Instance.Config.GameGuard == true)
// {
// uint uReturn = GameGuardHelper.InitCSAuth3("./support/GameGuard/");
// if (uReturn != 0)
// {
// Log.getLogger().error("Failed to Init GameGuard.");
// return false;
// }
// }
// _srv.AllowEmptyP2PGroup(true);
// string name = GameServerApp.Instance.Config.GameServerType.ToString();
// ServerName = ServerUtil.CreateServerName(serverType, ip,
// option.Port, myServerInfo.worldId, myServerInfo.channel);
// if (GameServerApp.Instance.Config.AWS.CloudWatchLog.Enable)
// {
// ServerLog.Init($"{serverType}Server", ip, option.Port,
// GameServerApp.Instance.Config.AWS.CloudWatchLog.CloudWatchLogGroup,
// GameServerApp.Instance.Config.AWS.CloudWatchLog.CloudWatchLogNamePattern,
// GameServerApp.Instance.Config.AWS.CloudWatchLog.CloudWatchLogLevel,
// GameServerApp.Instance.Config.AWS.Region,
// GameServerApp.Instance.Config.AWS.AccessKey,
// GameServerApp.Instance.Config.AWS.SecretKey,
// GameServerApp.Instance.Config.AWS.CloudWatchLog.CloudWatchLogLayout);
// }
// else
// {
// ServerLog.Init($"{serverType}Server", ip, option.Port);
// }
// string WorldServerName = $"{serverType}:{ServerUtil.MakeWorldidToString(myServerInfo.worldId)}";
// // 적용되지 않음. concurrentWrites=true 로 해결 인던서버와 게임서버를 로칼에서 실행할때
// // 로그파일이름이 중복되어 옵션을 켜줌. 실서비스시에는 끄는것이 좋음.
// //ServerLog.Init(logFileName);
// var param = new StartServerParameter();
// param.protocolVersion = new Nettention.Proud.Guid(ServerCommon.Constant.Version);
// param.tcpPorts.Add(option.Port);
// param.clientEmergencyLogMaxLineCount = 10;
// param.hostIDGenerationPolicySimplePacketMode = HostIDGenerationPolicy.HostIDGenerationPolicy_NoRecycle;
// param.m_enableAutoConnectionRecoveryOnServer = false;
// param.enableNagleAlgorithm = false;
// ///param.udpAssignMode = ServerUdpAssignMode.ServerUdpAssignMode_PerClient;
// //int udpPort = option.Port;
// //if (serverType != EServerType.Game)
// //{
// // udpPort = option.Port + 2500;
// //}
// //for (int i = 0; i < 2500; i++)
// //{
// // param.udpPorts.Add(udpPort + i);
// //}
// try
// {
//#if DEBUG
// // 서버와 오랫동안 통신이 되지 않을 때 서버와의 연결을 끊기 위한 타임아웃(초)의 임계값을 설정
// const Int32 SESSION_KEEP_ALIVE_TIME_MS = (60 * 60 * 1000) * 1; // 1시간 설정
// _srv.SetDefaultTimeoutTimeMs(SESSION_KEEP_ALIVE_TIME_MS);
//#else
// int keep_alive_time = GameServerApp.Instance.Config.SessionKeepAliveTimeSec * ConstValue.default_1000_millisec;
// _srv.SetDefaultTimeoutTimeMs(keep_alive_time);
//#endif//DEBUG
// //_srv.SetMessageMaxLength(ServerCommon.Constant.MaxPacketSize);
// _srv.Start(param);
// //_srv.EnableSpeedHackDetector();
// }
// catch (Exception ex)
// {
// Log.getLogger().error("Failed to start server~!!" + ex.ToString());
// return false;
// }
// if (GameServerApp.Instance.Config.GameServerType == EGameServerType.Channel)
// {
// if (TableData.Instance._WorldDataTable.TryGetValue(myServerInfo.worldId, out var value) == false)
// {
// Log.getLogger().error("Failed to start server~!! : Failed to read WorldDataTable.");
// return false;
// }
// Map = new Map(value.MapPath);
// }
// _runTask = new TaskCompletionSource<bool>();
// Log.getLogger().info($"running server on {option.Port}, {GameServerApp.Instance.Config.GameServerType}");
// _rabbitMQ4Game = new RabbitMQ4Game(ServerName
// , GameServerApp.Instance.Config.Rabbitmq.HostName
// , GameServerApp.Instance.Config.Rabbitmq.Port
// , GameServerApp.Instance.Config.Rabbitmq.UserName
// , GameServerApp.Instance.Config.Rabbitmq.Password
// , GameServerApp.Instance.Config.Rabbitmq.SSL);
// if (false == _rabbitMQ4Game.StartConsumer4Game())
// {
// Log.getLogger().error($"Failed to start server~!! : Failed to startConsumer RabbitMQ4Game !!!");
// return false;
// }
// ServerAuthClient serverAuthClient = new();
// _ = serverAuthClient.SendIPAsync(ServerName);
// string hostName = Dns.GetHostName();
// // 주기적 실행 task
// // 아래 StartNew의 호출 인자는 Task updateTask = Task.Run(() => Update()); 호출과 같음
// // https://code-maze.com/csharp-task-run-vs-task-factory-startnew/
// /*
// Task updateTask = LogicThread.Factory.StartNew(() => Update(),
// CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
// */
// bool firstInit = true;
// Task updateCUTask = ServerUtil.RunPeriodicTask(async () =>
// {
// try
// {
// await sessionUpdate();
// if (firstInit == true)
// {
// await Task.Run(async Task<bool>? () =>
// {
// await Task.Delay(1000);
// //서버 처음 뜰때 한번 호출 UpdateServerCU 이후에 부르기 위함.
// bool ret = await GameServerApp.Instance.ServerCUStorage.initAddSortedServerKey(
// ServerName,
// serverType,
// myServerInfo.worldId);
// if (ret == false)
// {
// Log.getLogger().error($"Add Sorted Server Key fail.");
// return false;
// }
// return true;
// }, _cts.Token);
// firstInit = false;
// }
// }
// catch (Exception e)
// {
// Log.getLogger().error(e.ToString());
// }
//#if DEBUG
// using (NetServerStats stat = _srv.GetStats())
// {
// //Log.getLogger().info($"tcp RCV:{stat.totalTcpReceiveBytes} tcp SND:{stat.totalTcpSendBytes} udp RCV:{stat.totalUdpReceiveBytes} udp SND:{stat.totalUdpSendBytes}");
// }
//#endif
// },
// TimeSpan.FromMilliseconds(5000), _cts.Token);
// Task updateTask = ServerUtil.RunPeriodicTask(async () =>
// {
// try
// {
// //Stopwatch stopwatch = Stopwatch.StartNew();
// await Update();
// /*stopwatch.Stop();
// if(stopwatch.ElapsedMilliseconds> 1000)
// Log.getLogger().error($"updateTask Slow log {stopwatch.ElapsedMilliseconds}");
// */
// }
// catch (Exception e)
// {
// Log.getLogger().error(e.ToString());
// }
// },
// TimeSpan.FromMilliseconds(300), _cts.Token);
// Task updateLoginTask = ServerUtil.RunPeriodicTask(async () =>
// {
// try
// {
// //Stopwatch stopwatch= Stopwatch.StartNew();
// await ClientSessionManager.Instance.ForEach(async (ClientSession session) =>
// {
// if (session.IsClosedProcessed == false)
// {
// //ClientSessionManager.Instance.ReleaseSession(session);
// //return false;
// await session.KeepLogin();
// await Task.Delay(10);
// }
// return true;
// });
// /*
// stopwatch.Stop();
// if (stopwatch.ElapsedMilliseconds > 1000)
// Log.getLogger().error($"updateLoginTask Slow log {stopwatch.ElapsedMilliseconds}");
// */
// }
// catch (Exception e)
// {
// Log.getLogger().error(e.ToString());
// }
// }, TimeSpan.FromMilliseconds(ServerCommon.Constant.KEEP_LOGIN_UPDATE_TIME), _cts.Token);
// //이벤트 업데이트가 100밀리 세컨드까지 필요할까? 1초면 될듯..
// Task updateEventCheckTask = ServerUtil.RunPeriodicTask(async () =>
// {
// try
// {
// EventUpdate();
// }
// catch (Exception e)
// {
// Log.getLogger().error(e.ToString());
// }
// },
// TimeSpan.FromMilliseconds(1000), _cts.Token);
// //퀘스트는 1초마다 처리해주면 될것 같은데... 이벤트랑 합쳐서 타이머를 돌리는 것도 나쁘지 않을듯....
// Task updateQuestCheckTask = ServerUtil.RunPeriodicTask(async () =>
// {
// try
// {
// await QuestUpdate();
// }
// catch (Exception e)
// {
// Log.getLogger().error(e.ToString());
// }
// },
// TimeSpan.FromMilliseconds(100), _cts.Token);
// if (serverType == ServerType.Game)
// {
// Task updateChannelInfoTask = ServerUtil.RunPeriodicTask(async () =>
// {
// try
// {
// ChannelInfoList.Clear();
// var serverInfoList = await GameServerApp.Instance.ServerCUStorage.
// getGameServerChannelInWorldServerCU(
// GameServer.Instance.ServerName);
// foreach (var channel in serverInfoList)
// {
// ChannelInfo channelInfo = new ChannelInfo();
// channelInfo.Channel = channel.Channel;
// channelInfo.Language = (int)ServerUtil.getLanguageByChannel(channel.Channel);
// channelInfo.Trafficlevel = GetTrafficLevel(channel.Sessions, channel.Capacity);
// ChannelInfoList.Add(channelInfo);
// }
// }
// catch (Exception e)
// {
// Log.getLogger().error(e.ToString());
// }
// }, TimeSpan.FromMilliseconds(ServerCommon.Constant.CHANNEL_UPDATE_TIME), _cts.Token);
// periodicTasks.Add(updateChannelInfoTask);
// }
// if (GameServerApp.Instance.Config.GameGuard == true)
// {
// Task updateGameGuardTask = ServerUtil.RunPeriodicTask(async () =>// -- GameGuard
// {
// try
// {
// await ClientSessionManager.Instance.ForEach(async (ClientSession session) =>
// {
// if (GameGuardHelper.getGameGuardPacket(session.GameGuardInstance, out var packet, out var packetSize) == false)
// {
// await session.Close();
// }
// ClientToGame clientToGame = new ClientToGame();
// clientToGame.Message = new();
// clientToGame.Message.GameGuardAuthNoti = new();
// clientToGame.Message.GameGuardAuthNoti.AuthValue.AddRange(Array.ConvertAll<byte, int>(packet, Convert.ToInt32).ToList());
// clientToGame.Message.GameGuardAuthNoti.AuthValueSize = packetSize;
// session.Send(RmiContext.ReliableSend, clientToGame);
// return true;
// });
// }
// catch (Exception e)
// {
// Log.getLogger().error(e.ToString());
// }
// }, TimeSpan.FromMinutes(ServerCommon.Constant.UPDATE_GAMEGUARD_AUTH), _cts.Token);
// periodicTasks.Add(updateGameGuardTask);
// }
// Task updateChatTask = ServerUtil.RunPeriodicTask(async () =>
// {
// NoticeChatManager.Instance.UpdateChat();
// }, TimeSpan.FromMilliseconds(ServerCommon.Constant.NOTICE_CHAT_UPDATE_TIME), _cts.Token);
// var keepPartyTask = PartyManager.Instance.KeepParty(_cts.Token);
// periodicTasks.Add(updateLoginTask);
// periodicTasks.Add(updateTask);
// periodicTasks.Add(updateCUTask);
// periodicTasks.Add(updateChatTask);
// periodicTasks.Add(keepPartyTask);
// periodicTasks.Add(updateEventCheckTask);
// return true;
// }
// public async Task sessionUpdate()
// {
// int roomCapacity = 0;
// if (GameServerApp.Instance.Config.GameServerType == EGameServerType.Indun)
// {
// roomCapacity = InstanceRoomManager.Instance.Capacity;
// }
// (bool ret, _) = await GameServerApp.Instance.ServerCUStorage.UpdateServerCU(
// GameServer.Instance.ServerName,
// GameServer.Instance.myServerInfo.ip,
// GameServer.Instance.myServerInfo.port,
// ClientSessionManager.Instance.Count,
// Constant.g_MaxUser,
// GameServer.Instance.myServerInfo.instanceId,
// GameServer.Instance.myServerInfo.worldId,
// GameServer.Instance.myServerInfo.channel,
// ServerUtil.getLanguageByChannel(GameServer.Instance.myServerInfo.channel),
// roomCapacity);
// if (ret == false)
// {
// Log.getLogger().warn(
// $"GameServerCU Login Update fail {GameServerApp.Instance.Config.GameServerType}{GameServer.Instance.myServerInfo.ip}:{GameServer.Instance.myServerInfo.port} count:{ClientSessionManager.Instance.Count}");
// }
// ServerType serverType = GameServerApp.Instance.Config.GameServerType == EGameServerType.Channel ? ServerType.Game : ServerType.Indun;
// MQHelper.SendSessionCount(GameServer.Instance._rabbitMQ4Game, GameServer.Instance.myServerInfo.instanceId, ClientSessionManager.Instance.Count, (int)serverType, GameServer.Instance.myServerInfo.worldId);
// }
// public async Task StopServer()
// {
// await GameServerApp.Instance.ServerCUStorage.DeleteServerInfo(ServerName);
// _srv.Stop();
// _cts.Cancel();
// _rabbitMQ4Game?.stop();
// if (GameServerApp.Instance.Config.GameGuard == true)
// {
// GameGuardHelper.CloseCSAuth3();
// }
// await NamedPipeMonitor.StopNamedPipeService();
// Task.WaitAll(periodicTasks.ToArray());
// _runTask?.SetResult(true);
// }
// public Task? Running()
// {
// return _runTask?.Task;
// }
// public bool Send(HostID hostID, RmiContext rmi, ClientToGame msg)
// {
// if (msg.Message is null || msg.Message.MsgCase != ClientToGameMessage.MsgOneofCase.MoveActor)
// {
// Log.getLogger().info($"{msg.MsgCase} size:{msg.CalculateSize()}");
// }
// return _proxy.Message(hostID, rmi, msg);
// }
// public bool Send(HostID[] hostID, ClientToGame msg)
// {
// Log.getLogger().info($"{msg.MsgCase} size:{msg.CalculateSize()}");
// return _proxy.Message(hostID, ServerCore.ProudNetHelper.compressRmi(), msg);
// }
// public bool BroadCastingAll(ClientToGame msg)
// {
// Log.getLogger().info($"{msg.MsgCase} size:{msg.CalculateSize()}");
// return _proxy.Message(_srv.GetClientHostIDs(), ServerCore.ProudNetHelper.compressRmi(), msg);
// }
// async Task Update()
// {
// await ProcessBuff();
// }
// private static async Task ProcessBuff()
// {
// await ClientSessionManager.Instance.ForEach((ClientSession session) =>
// {
// session.CheckBuff();
// return Task.FromResult(true);
// });
// }
// void EventUpdate()
// {
// EventManager.Instance.ClaimEventActiveCheck();
// }
// async Task QuestUpdate()
// {
// }
// public List<ChannelInfo> GetChannelInfoList()
// {
// return ChannelInfoList;
// }
// public int GetTrafficLevel(int CurUser, int MaxUser)
// {
// double trafficPercent = (double)CurUser / (double)MaxUser * (double)100;
// int trafficLevel = 0;
// if (0 <= trafficPercent && trafficPercent < 80.0f)
// {
// trafficLevel = 0;
// }
// else if (80.0f <= trafficPercent && trafficPercent < 100.0f)
// {
// trafficLevel = 1;
// }
// else if (100.0f <= trafficPercent)
// {
// trafficLevel = 2;
// }
// return trafficLevel;
// }
// public AtomicBool getUserLoginBlockEnable()
// {
// return m_user_login_block_enable;
// }
// public async Task logoutUserAllByKick()
// {
// var sessions = ClientSessionManager.Instance.getClientSessions().Values.ToList();
// foreach (var session in sessions)
// {
// await ClientSessionManager.Instance.Kick(session.getUserNickname());
// }
// }
// }
//}