protected virtual void ProcessMediusMessage(BaseMediusMessage message, IChannel clientChannel, ChannelData data) { if (message == null) { return; } switch (message) { #if DEBUG #region Dme case MediusServerSessionBeginRequest mgclSessionBeginRequest: { // Create DME object data.ClientObject = Program.ProxyServer.ReserveDMEObject(mgclSessionBeginRequest); // data.ClientObject.OnConnected(); // Reply data.ClientObject.Queue(new MediusServerSessionBeginResponse() { MessageID = mgclSessionBeginRequest.MessageID, Confirmation = MGCL_ERROR_CODE.MGCL_SUCCESS, ConnectInfo = new NetConnectionInfo() { AccessKey = data.ClientObject.Token, SessionKey = data.ClientObject.SessionKey, WorldID = 0, ServerKey = Program.GlobalAuthPublic, AddressList = new NetAddressList() { AddressList = new NetAddress[Constants.NET_ADDRESS_LIST_COUNT] { new NetAddress() { Address = Program.LobbyServer.IPAddress.ToString(), Port = (uint)Program.ProxyServer.Port, AddressType = NetAddressType.NetAddressTypeExternal }, new NetAddress() { Address = Program.Settings.NATIp, Port = (uint)Program.Settings.NATPort, AddressType = NetAddressType.NetAddressTypeNATService }, } }, Type = NetConnectionType.NetConnectionTypeClientServerTCP } }); break; } case MediusServerAuthenticationRequest mgclAuthRequest: { var dmeObject = data.ClientObject as DMEObject; if (dmeObject == null) { throw new InvalidOperationException($"Non-DME Client sending MGCL messages."); } // dmeObject.SetIp(mgclAuthRequest.AddressList.AddressList[0].Address); // Keep the client alive until the dme objects connects to MPS or times out dmeObject.KeepAliveUntilNextConnection(); // Reply dmeObject.Queue(new MediusServerAuthenticationResponse() { MessageID = mgclAuthRequest.MessageID, Confirmation = MGCL_ERROR_CODE.MGCL_SUCCESS, ConnectInfo = new NetConnectionInfo() { AccessKey = dmeObject.Token, SessionKey = dmeObject.SessionKey, WorldID = 0, ServerKey = Program.GlobalAuthPublic, AddressList = new NetAddressList() { AddressList = new NetAddress[Constants.NET_ADDRESS_LIST_COUNT] { new NetAddress() { Address = Program.ProxyServer.IPAddress.ToString(), Port = (uint)Program.ProxyServer.Port, AddressType = NetAddressType.NetAddressTypeExternal }, new NetAddress() { Address = Program.Settings.NATIp, Port = (uint)Program.Settings.NATPort, AddressType = NetAddressType.NetAddressTypeNATService }, } }, Type = NetConnectionType.NetConnectionTypeClientServerTCP } }); break; } case MediusServerSetAttributesRequest mgclSetAttrRequest: { var dmeObject = data.ClientObject as DMEObject; if (dmeObject == null) { throw new InvalidOperationException($"Non-DME Client sending MGCL messages."); } // Reply with success dmeObject.Queue(new MediusServerSetAttributesResponse() { MessageID = mgclSetAttrRequest.MessageID, Confirmation = MGCL_ERROR_CODE.MGCL_SUCCESS }); break; } #endregion #endif #region Session case MediusExtendedSessionBeginRequest extendedSessionBeginRequest: { // Create client object data.ClientObject = Program.LobbyServer.ReserveClient(extendedSessionBeginRequest); data.ClientObject.ApplicationId = data.ApplicationId; data.ClientObject.OnConnected(); // Reply data.ClientObject.Queue(new MediusSessionBeginResponse() { MessageID = extendedSessionBeginRequest.MessageID, SessionKey = data.ClientObject.SessionKey, StatusCode = MediusCallbackStatus.MediusSuccess }); break; } case MediusSessionBeginRequest sessionBeginRequest: { // Create client object data.ClientObject = Program.LobbyServer.ReserveClient(sessionBeginRequest); data.ClientObject.ApplicationId = data.ApplicationId; data.ClientObject.OnConnected(); // Reply data.ClientObject.Queue(new MediusSessionBeginResponse() { MessageID = sessionBeginRequest.MessageID, SessionKey = data.ClientObject.SessionKey, StatusCode = MediusCallbackStatus.MediusSuccess }); break; } case MediusSessionEndRequest sessionEndRequest: { if (data.ClientObject == null) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} is trying to end session without an Client Object"); } // Remove data.ClientObject.EndSession(); // data.ClientObject = null; Queue(new RT_MSG_SERVER_APP() { Message = new MediusSessionEndResponse() { MessageID = sessionEndRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, } }, clientChannel); break; } #endregion case MediusSetLocalizationParamsRequest setLocalizationParamsRequest: { if (data.ClientObject == null) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} sent {setLocalizationParamsRequest} without a session."); } data.ClientObject.Queue(new MediusSetLocalizationParamsResponse() { MessageID = setLocalizationParamsRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess }); break; } case MediusDnasSignaturePost dnasSignaturePost: { break; } #region Account case MediusAccountRegistrationRequest accountRegRequest: { if (data.ClientObject == null) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} sent {accountRegRequest} without a session."); } // Check that account creation is enabled if (Program.Settings.Beta != null && Program.Settings.Beta.Enabled && !Program.Settings.Beta.AllowAccountCreation) { // Reply error data.ClientObject.Queue(new MediusAccountRegistrationResponse() { MessageID = accountRegRequest.MessageID, StatusCode = MediusCallbackStatus.MediusFail }); return; } _ = Program.Database.CreateAccount(new Database.Models.CreateAccountDTO() { AccountName = accountRegRequest.AccountName, AccountPassword = Utils.ComputeSHA256(accountRegRequest.Password), MachineId = null, MediusStats = Convert.ToBase64String(new byte[Constants.ACCOUNTSTATS_MAXLEN]), AppId = data.ClientObject.ApplicationId }).ContinueWith((r) => { if (r.IsCompletedSuccessfully && r.Result != null) { // Reply with account id data.ClientObject.Queue(new MediusAccountRegistrationResponse() { MessageID = accountRegRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, AccountID = r.Result.AccountId }); } else { // Reply error data.ClientObject.Queue(new MediusAccountRegistrationResponse() { MessageID = accountRegRequest.MessageID, StatusCode = MediusCallbackStatus.MediusAccountAlreadyExists }); } }); break; } case MediusAccountGetIDRequest accountGetIdRequest: { if (data.ClientObject == null) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} sent {accountGetIdRequest} without a session."); } _ = Program.Database.GetAccountByName(accountGetIdRequest.AccountName).ContinueWith((r) => { if (r.IsCompletedSuccessfully && r.Result != null) { // Success data?.ClientObject?.Queue(new MediusAccountGetIDResponse() { MessageID = accountGetIdRequest.MessageID, AccountID = r.Result.AccountId, StatusCode = MediusCallbackStatus.MediusSuccess }); } else { // Fail data?.ClientObject?.Queue(new MediusAccountGetIDResponse() { MessageID = accountGetIdRequest.MessageID, AccountID = -1, StatusCode = MediusCallbackStatus.MediusAccountNotFound }); } }); break; } case MediusAccountDeleteRequest accountDeleteRequest: { // ERROR - Need a session if (data.ClientObject == null) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} sent {accountDeleteRequest} without a session."); } // ERROR -- Need to be logged in if (!data.ClientObject.IsLoggedIn) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} sent {accountDeleteRequest} without a being logged in."); } _ = Program.Database.DeleteAccount(data.ClientObject.AccountName).ContinueWith((r) => { if (r.IsCompletedSuccessfully && r.Result) { Logger.Info($"Delete account {data?.ClientObject?.AccountName}"); data?.ClientObject?.Logout(); data?.ClientObject?.Queue(new MediusAccountDeleteResponse() { MessageID = accountDeleteRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess }); } else { data?.ClientObject?.Queue(new MediusAccountDeleteResponse() { MessageID = accountDeleteRequest.MessageID, StatusCode = MediusCallbackStatus.MediusDBError }); } }); break; } case MediusAnonymousLoginRequest anonymousLoginRequest: { if (data.ClientObject == null) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} sent {anonymousLoginRequest} without a session."); } data.ClientObject.Queue(new MediusAnonymousLoginResponse() { MessageID = anonymousLoginRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, AccountID = -1, AccountType = MediusAccountType.MediusMasterAccount, MediusWorldID = Program.Manager.GetDefaultLobbyChannel(data.ApplicationId).Id, ConnectInfo = new NetConnectionInfo() { SessionKey = anonymousLoginRequest.SessionKey, WorldID = 0, ServerKey = Program.GlobalAuthPublic, AddressList = new NetAddressList() { AddressList = new NetAddress[Constants.NET_ADDRESS_LIST_COUNT] { new NetAddress() { Address = Program.LobbyServer.IPAddress.ToString(), Port = (uint)Program.LobbyServer.Port, AddressType = NetAddressType.NetAddressTypeExternal }, new NetAddress() { Address = Program.Settings.NATIp, Port = (uint)Program.Settings.NATPort, AddressType = NetAddressType.NetAddressTypeNATService }, } }, Type = NetConnectionType.NetConnectionTypeClientServerTCP } }); break; } case MediusAccountLoginRequest accountLoginRequest: { // ERROR - Need a session if (data.ClientObject == null) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} sent {accountLoginRequest} without a session."); } // Check the client isn't already logged in if (Program.Manager.GetClientByAccountName(accountLoginRequest.Username)?.IsLoggedIn ?? false) { data.ClientObject.Queue(new MediusAccountLoginResponse() { MessageID = accountLoginRequest.MessageID, StatusCode = MediusCallbackStatus.MediusAccountLoggedIn }); } else { Program.Database.GetAccountByName(accountLoginRequest.Username).ContinueWith((r) => { if (data == null || data.ClientObject == null || !data.ClientObject.IsConnected) { return; } if (r.IsCompletedSuccessfully && r.Result != null && data != null && data.ClientObject != null && data.ClientObject.IsConnected) { if (r.Result.IsBanned) { // Send ban message QueueBanMessage(data); // Account is banned // Temporary solution is to tell the client the login failed data?.ClientObject?.Queue(new MediusAccountLoginResponse() { MessageID = accountLoginRequest.MessageID, StatusCode = MediusCallbackStatus.MediusAccountBanned }); } else if (Program.Settings.Beta != null && Program.Settings.Beta.Enabled && Program.Settings.Beta.RestrictSignin && !Program.Settings.Beta.PermittedAccounts.Contains(r.Result.AccountName)) { // Account not allowed to sign in data?.ClientObject?.Queue(new MediusAccountLoginResponse() { MessageID = accountLoginRequest.MessageID, StatusCode = MediusCallbackStatus.MediusFail }); } else if (Utils.ComputeSHA256(accountLoginRequest.Password) == r.Result.AccountPassword) { // data.ClientObject.Login(r.Result); // Update db ip _ = Program.Database.PostAccountIp(r.Result.AccountId, (clientChannel.RemoteAddress as IPEndPoint).Address.MapToIPv4().ToString()); // Add to logged in clients Program.Manager.AddClient(data.ClientObject); // Logger.Info($"LOGGING IN AS {data.ClientObject.AccountName} with access token {data.ClientObject.Token}"); // Put client in default channel data.ClientObject.JoinChannel(Program.Manager.GetDefaultLobbyChannel(data.ApplicationId)); // Tell client data.ClientObject.Queue(new MediusAccountLoginResponse() { MessageID = accountLoginRequest.MessageID, AccountID = data.ClientObject.AccountId, AccountType = MediusAccountType.MediusMasterAccount, ConnectInfo = new NetConnectionInfo() { AccessKey = data.ClientObject.Token, SessionKey = data.ClientObject.SessionKey, WorldID = Program.Manager.GetDefaultLobbyChannel(data.ApplicationId).Id, ServerKey = Program.GlobalAuthPublic, AddressList = new NetAddressList() { AddressList = new NetAddress[Constants.NET_ADDRESS_LIST_COUNT] { new NetAddress() { Address = Program.LobbyServer.IPAddress.ToString(), Port = (uint)Program.LobbyServer.Port, AddressType = NetAddressType.NetAddressTypeExternal }, new NetAddress() { Address = Program.Settings.NATIp, Port = (uint)Program.Settings.NATPort, AddressType = NetAddressType.NetAddressTypeNATService }, } }, Type = NetConnectionType.NetConnectionTypeClientServerTCP }, MediusWorldID = Program.Manager.GetDefaultLobbyChannel(data.ApplicationId).Id, StatusCode = MediusCallbackStatus.MediusSuccess }); // Prepare for transition to lobby server data.ClientObject.KeepAliveUntilNextConnection(); } else { // Incorrect password data?.ClientObject?.Queue(new MediusAccountLoginResponse() { MessageID = accountLoginRequest.MessageID, StatusCode = MediusCallbackStatus.MediusInvalidPassword }); } } else { // Account not found data.ClientObject.Queue(new MediusAccountLoginResponse() { MessageID = accountLoginRequest.MessageID, StatusCode = MediusCallbackStatus.MediusAccountNotFound, }); } }); } break; } case MediusAccountLogoutRequest accountLogoutRequest: { // ERROR - Need a session if (data.ClientObject == null) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} sent {accountLogoutRequest} without a session."); } MediusCallbackStatus result = MediusCallbackStatus.MediusFail; // Check token if (data.ClientObject.IsLoggedIn && accountLogoutRequest.SessionKey == data.ClientObject.SessionKey) { // result = MediusCallbackStatus.MediusSuccess; // Logout data.ClientObject.Logout(); } data.ClientObject.Queue(new MediusAccountLogoutResponse() { MessageID = accountLogoutRequest.MessageID, StatusCode = result }); break; } case MediusTextFilterRequest textFilterRequest: { if (data.ClientObject == null) { throw new InvalidOperationException($"INVALID OPERATION: {clientChannel} sent {textFilterRequest} without a session."); } // Deny special characters // Also trim any whitespace switch (textFilterRequest.TextFilterType) { case MediusTextFilterType.MediusTextFilterPassFail: { if (textFilterRequest.Text.Any(x => x < 0x20 || x >= 0x7F)) { // Failed due to special characters data.ClientObject.Queue(new MediusTextFilterResponse() { MessageID = textFilterRequest.MessageID, StatusCode = MediusCallbackStatus.MediusFail }); } else { // data.ClientObject.Queue(new MediusTextFilterResponse() { MessageID = textFilterRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, Text = textFilterRequest.Text.Trim() }); } break; } case MediusTextFilterType.MediusTextFilterReplace: { data.ClientObject.Queue(new MediusTextFilterResponse() { MessageID = textFilterRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, Text = String.Concat(textFilterRequest.Text.Trim().Where(x => x >= 0x20 && x < 0x7F)) }); break; } } break; } #endregion #region Policy / Announcements case MediusGetAllAnnouncementsRequest getAllAnnouncementsRequest: { // Send to plugins Program.Plugins.OnEvent(PluginEvent.MEDIUS_PLAYER_ON_GET_ALL_ANNOUNCEMENTS, new OnPlayerRequestArgs() { Player = data.ClientObject, Request = getAllAnnouncementsRequest }); Program.Database.GetLatestAnnouncements().ContinueWith((r) => { if (data == null || data.ClientObject == null || !data.ClientObject.IsConnected) { return; } if (r.IsCompletedSuccessfully && r.Result != null && r.Result.Length > 0) { List <MediusGetAnnouncementsResponse> responses = new List <MediusGetAnnouncementsResponse>(); foreach (var result in r.Result) { responses.Add(new MediusGetAnnouncementsResponse() { MessageID = getAllAnnouncementsRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, Announcement = string.IsNullOrEmpty(result.AnnouncementTitle) ? $"{result.AnnouncementBody}" : $"{result.AnnouncementTitle}\n{result.AnnouncementBody}\n", AnnouncementID = result.Id, EndOfList = false }); } responses[responses.Count - 1].EndOfList = true; data.ClientObject.Queue(responses); } else { data.ClientObject.Queue(new MediusGetAnnouncementsResponse() { MessageID = getAllAnnouncementsRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, Announcement = "", AnnouncementID = 0, EndOfList = true }); } }); break; } case MediusGetAnnouncementsRequest getAnnouncementsRequest: { // Send to plugins Program.Plugins.OnEvent(PluginEvent.MEDIUS_PLAYER_ON_GET_ANNOUNCEMENTS, new OnPlayerRequestArgs() { Player = data.ClientObject, Request = getAnnouncementsRequest }); Program.Database.GetLatestAnnouncement().ContinueWith((r) => { if (data == null || data.ClientObject == null || !data.ClientObject.IsConnected) { return; } if (r.IsCompletedSuccessfully && r.Result != null) { data.ClientObject.Queue(new MediusGetAnnouncementsResponse() { MessageID = getAnnouncementsRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, Announcement = string.IsNullOrEmpty(r.Result.AnnouncementTitle) ? $"{r.Result.AnnouncementBody}" : $"{r.Result.AnnouncementTitle}\n{r.Result.AnnouncementBody}\n", AnnouncementID = r.Result.Id, EndOfList = true }); } else { data.ClientObject.Queue(new MediusGetAnnouncementsResponse() { MessageID = getAnnouncementsRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, Announcement = "", AnnouncementID = 0, EndOfList = true }); } }); break; } case MediusGetPolicyRequest getPolicyRequest: { // Send to plugins Program.Plugins.OnEvent(PluginEvent.MEDIUS_PLAYER_ON_GET_POLICY, new OnPlayerRequestArgs() { Player = data.ClientObject, Request = getPolicyRequest }); switch (getPolicyRequest.Policy) { case MediusPolicyType.Privacy: { Program.Database.GetUsagePolicy().ContinueWith((r) => { if (data == null || data.ClientObject == null || !data.ClientObject.IsConnected) { return; } if (r.IsCompletedSuccessfully && r.Result != null) { string txt = r.Result.EulaBody; if (!string.IsNullOrEmpty(r.Result.EulaTitle)) { txt = r.Result.EulaTitle + "\n" + txt; } data.ClientObject.Queue(MediusGetPolicyResponse.FromText(getPolicyRequest.MessageID, txt)); } else { data.ClientObject.Queue(new MediusGetPolicyResponse() { MessageID = getPolicyRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, Policy = "", EndOfText = true }); } }); break; } case MediusPolicyType.Usage: { Program.Database.GetUsagePolicy().ContinueWith((r) => { if (data == null || data.ClientObject == null || !data.ClientObject.IsConnected) { return; } if (r.IsCompletedSuccessfully && r.Result != null) { string txt = r.Result.EulaBody; if (!string.IsNullOrEmpty(r.Result.EulaTitle)) { txt = r.Result.EulaTitle + "\n" + txt; } data.ClientObject.Queue(MediusGetPolicyResponse.FromText(getPolicyRequest.MessageID, txt)); } else { data.ClientObject.Queue(new MediusGetPolicyResponse() { MessageID = getPolicyRequest.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, Policy = "", EndOfText = true }); } }); break; } } break; } #endregion #region Deadlocked No-op Messages (MAS) case MediusGetBuddyList_ExtraInfoRequest getBuddyList_ExtraInfoRequest: { Queue(new RT_MSG_SERVER_APP() { Message = new MediusGetBuddyList_ExtraInfoResponse() { MessageID = getBuddyList_ExtraInfoRequest.MessageID, StatusCode = MediusCallbackStatus.MediusNoResult, EndOfList = true } }, clientChannel); break; } case MediusGetIgnoreListRequest getIgnoreListRequest: { Queue(new RT_MSG_SERVER_APP() { Message = new MediusGetIgnoreListResponse() { MessageID = getIgnoreListRequest.MessageID, StatusCode = MediusCallbackStatus.MediusNoResult, EndOfList = true } }, clientChannel); break; } case MediusGetMyClansRequest getMyClansRequest: { Queue(new RT_MSG_SERVER_APP() { Message = new MediusGetMyClansResponse() { MessageID = getMyClansRequest.MessageID, StatusCode = MediusCallbackStatus.MediusNoResult, EndOfList = true } }, clientChannel); break; } #endregion default: { Logger.Warn($"Unhandled Medius Message: {message}"); break; } } }
protected override int HandleCommand(BaseMessage message, ClientSocket client, ref List <BaseMessage> responses) { // Log if id is set if (Program.Settings.IsLog(message.Id)) { Console.WriteLine($"MAS {client}: {message}"); } // Update client echo client.ClientObject?.OnEcho(DateTime.UtcNow); // switch (message.Id) { case RT_MSG_TYPE.RT_MSG_CLIENT_HELLO: //Connecting 1 responses.Add(new RT_MSG_SERVER_HELLO()); break; case RT_MSG_TYPE.RT_MSG_CLIENT_CRYPTKEY_PUBLIC: { responses.Add(new RT_MSG_SERVER_CRYPTKEY_PEER() { Key = Utils.FromString(Program.KEY) }); break; } case RT_MSG_TYPE.RT_MSG_CLIENT_CONNECT_TCP: { var msg = message as RT_MSG_CLIENT_CONNECT_TCP; // Set app id of client client.ApplicationId = msg.AppId; responses.Add(new RT_MSG_SERVER_CONNECT_REQUIRE() { Contents = Utils.FromString("024802") }); break; } case RT_MSG_TYPE.RT_MSG_CLIENT_CONNECT_READY_REQUIRE: { responses.Add(new RT_MSG_SERVER_CRYPTKEY_GAME() { Key = Utils.FromString(Program.KEY) }); responses.Add(new RT_MSG_SERVER_CONNECT_ACCEPT_TCP() { UNK_02 = 0x00, UNK_03 = 0x00, IP = (client.RemoteEndPoint as IPEndPoint)?.Address }); break; } case RT_MSG_TYPE.RT_MSG_CLIENT_CONNECT_READY_TCP: { responses.Add(new RT_MSG_SERVER_CONNECT_COMPLETE() { ARG1 = 0x0001 }); responses.Add(new RT_MSG_SERVER_ECHO()); break; } case RT_MSG_TYPE.RT_MSG_SERVER_ECHO: { client.ClientObject?.OnEcho(DateTime.UtcNow); break; } case RT_MSG_TYPE.RT_MSG_CLIENT_APP_TOSERVER: { var appMsg = (message as RT_MSG_CLIENT_APP_TOSERVER).AppMessage; switch (appMsg.Id) { // case MediusAppPacketIds.MediusServerSessionBeginRequest: { var msg = appMsg as MediusServerSessionBeginRequest; // Create DME object var clientObject = new DMEObject(msg); Program.Clients.Add(clientObject); client.SetToken(clientObject.Token); client.ApplicationId = msg.ApplicationID; responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusServerSessionBeginResponse() { MessageID = msg.MessageID, Confirmation = MGCL_ERROR_CODE.MGCL_SUCCESS, ConnectInfo = new NetConnectionInfo() { AccessKey = clientObject.Token, SessionKey = clientObject.SessionKey, WorldID = 0, ServerKey = Program.GlobalAuthPublic, AddressList = new NetAddressList() { AddressList = new NetAddress[MediusConstants.NET_ADDRESS_LIST_COUNT] { new NetAddress() { Address = Program.SERVER_IP.ToString(), Port = (uint)Program.ProxyServer.Port, AddressType = NetAddressType.NetAddressTypeExternal }, //new NetAddress() { AddressType = NetAddressType.NetAddressNone } new NetAddress() { Address = Program.SERVER_IP.ToString(), Port = (uint)Program.NATServer.Port, AddressType = NetAddressType.NetAddressTypeNATService }, } }, Type = NetConnectionType.NetConnectionTypeClientServerTCP } } }); break; } case MediusAppPacketIds.MediusServerAuthenticationRequest: { var msg = appMsg as MediusServerAuthenticationRequest; if (client.ClientObject is DMEObject dmeObject) { // dmeObject.SetIp(msg.AddressList.AddressList[0].Address); // Override the dme server ip if (!string.IsNullOrEmpty(Program.Settings.DmeIpOverride)) { dmeObject.SetIp(Program.Settings.DmeIpOverride); } } responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusServerAuthenticationResponse() { MessageID = msg.MessageID, Confirmation = MGCL_ERROR_CODE.MGCL_SUCCESS, ConnectInfo = new NetConnectionInfo() { AccessKey = client.ClientObject.Token, SessionKey = client.ClientObject.SessionKey, WorldID = 0, ServerKey = Program.GlobalAuthPublic, AddressList = new NetAddressList() { AddressList = new NetAddress[MediusConstants.NET_ADDRESS_LIST_COUNT] { new NetAddress() { Address = Program.SERVER_IP.ToString(), Port = (uint)Program.ProxyServer.Port, AddressType = NetAddressType.NetAddressTypeExternal }, //new NetAddress() { AddressType = NetAddressType.NetAddressNone } new NetAddress() { Address = Program.SERVER_IP.ToString(), Port = (uint)Program.NATServer.Port, AddressType = NetAddressType.NetAddressTypeNATService }, } }, Type = NetConnectionType.NetConnectionTypeClientServerTCP } } }); break; } case MediusAppPacketIds.MediusServerSetAttributesRequest: { var msg = appMsg as MediusServerSetAttributesRequest; responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusServerSetAttributesResponse() { MessageID = msg.MessageID, Confirmation = MGCL_ERROR_CODE.MGCL_SUCCESS } }); break; } // case MediusAppPacketIds.SessionBegin: { var msg = appMsg as MediusSessionBeginRequest; responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusSessionBeginResponse() { MessageID = msg.MessageID, SessionKey = Program.GenerateSessionKey(), StatusCode = MediusCallbackStatus.MediusSuccess } }); break; } case MediusAppPacketIds.SessionEnd: { var msg = appMsg as MediusSessionEndRequest; responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusSessionEndResponse() { MessageID = msg.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, } }); break; } case MediusAppPacketIds.ExtendedSessionBeginRequest: { var sessionBeginMsg = appMsg as MediusExtendedSessionBeginRequest; responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusSessionBeginResponse() { MessageID = sessionBeginMsg.MessageID, SessionKey = Program.GenerateSessionKey(), StatusCode = MediusCallbackStatus.MediusSuccess } }); break; } case MediusAppPacketIds.SetLocalizationParams: { var localizationMsg = appMsg as MediusSetLocalizationParamsRequest; responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusSetLocalizationParamsResponse() { MessageID = localizationMsg.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess } }); break; } case MediusAppPacketIds.DnasSignaturePost: { var msg = appMsg as MediusDnasSignaturePost; break; } case MediusAppPacketIds.AccountRegistration: { var msg = appMsg as MediusAccountRegistrationRequest; // Ensure account doesn't already exist if (Program.Database.TryGetAccountByName(msg.AccountName, out var account)) { responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusAccountRegistrationResponse() { MessageID = msg.MessageID, StatusCode = MediusCallbackStatus.MediusAccountAlreadyExists } }); } else { // Create new account account = new Account() { AccountName = msg.AccountName, AccountPassword = BCrypt.Net.BCrypt.HashPassword(msg.Password), }; // Add to collection Program.Database.AddAccount(account); // Reply with account id responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusAccountRegistrationResponse() { MessageID = msg.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, AccountID = account.AccountId } }); } break; } case MediusAppPacketIds.AccountGetID: { var msg = appMsg as MediusAccountGetIDRequest; int?accountId = null; // Try to grab account id if (Program.Database.TryGetAccountByName(msg.AccountName, out var account)) { accountId = account.AccountId; } // Return id responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusAccountGetIDResponse() { MessageID = msg.MessageID, AccountID = accountId ?? 0, StatusCode = accountId.HasValue ? MediusCallbackStatus.MediusSuccess : MediusCallbackStatus.MediusAccountNotFound } }); break; } // case MediusAppPacketIds.AccountDelete: // { // var msg = appMsg as MediusAccountDeleteRequest; // var status = MediusCallbackStatus.MediusFail; // // // var account = client.ClientObject?.ClientAccount; // // Ensure logged in // if (account != null) // { // // Double check password // if (account.AccountPassword == msg.MasterPassword) // { // // Delete // Program.Database.DeleteAccount(account); // client.ClientObject.Logout(); // status = MediusCallbackStatus.MediusSuccess; // } // } // responses.Add(new RT_MSG_SERVER_APP() // { // AppMessage = new MediusAccountDeleteResponse() // { // MessageID = msg.MessageID, // StatusCode = status // } // }); // Console.WriteLine($"Delete account {account?.AccountName} {status}"); // break; // } case MediusAppPacketIds.AnonymousLogin: { var msg = appMsg as MediusAnonymousLoginRequest; responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusAnonymousLoginResponse() { MessageID = msg.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, AccountID = -1, AccountType = MediusAccountType.MediusMasterAccount, MediusWorldID = Program.Settings.DefaultChannelId, ConnectInfo = new NetConnectionInfo() { SessionKey = msg.SessionKey, WorldID = 0, ServerKey = Program.GlobalAuthPublic, AddressList = new NetAddressList() { AddressList = new NetAddress[MediusConstants.NET_ADDRESS_LIST_COUNT] { new NetAddress() { Address = Program.SERVER_IP.ToString(), Port = (uint)Program.LobbyServer.Port, AddressType = NetAddressType.NetAddressTypeExternal }, //new NetAddress() { AddressType = NetAddressType.NetAddressNone} new NetAddress() { Address = Program.SERVER_IP.ToString(), Port = (uint)Program.NATServer.Port, AddressType = NetAddressType.NetAddressTypeNATService }, } }, Type = NetConnectionType.NetConnectionTypeClientServerTCP } } }); break; } case MediusAppPacketIds.AccountLogin: { var loginMsg = appMsg as MediusAccountLoginRequest; Console.WriteLine($"LOGIN REQUEST: {loginMsg}"); // Find account if (!Program.Database.TryGetAccountByName(loginMsg.Username, out var account)) { responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusAccountLoginResponse() { MessageID = loginMsg.MessageID, StatusCode = MediusCallbackStatus.MediusAccountNotFound, } }); } // Check client isn't already logged in else if (account.IsLoggedIn) { responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusAccountLoginResponse() { MessageID = loginMsg.MessageID, StatusCode = MediusCallbackStatus.MediusAccountLoggedIn } }); } else if (BCrypt.Net.BCrypt.Verify(loginMsg.Password, account.AccountPassword) == false) { responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusAccountLoginResponse() { MessageID = loginMsg.MessageID, StatusCode = MediusCallbackStatus.MediusInvalidPassword } }); } else { // var clientObject = new ClientObject(account, client.ApplicationId, loginMsg.SessionKey); clientObject.Status = MediusPlayerStatus.MediusPlayerInAuthWorld; // Program.Clients.Add(clientObject); // client.SetToken(clientObject.Token); // Console.WriteLine($"LOGGING IN AS {account.AccountName} with access token {clientObject.Token}"); // Send cheats if (Program.Settings.Patches != null) { foreach (var patch in Program.Settings.Patches) { if (patch.Enabled && patch.ApplicationId == client.ApplicationId) { responses.AddRange(patch.Serialize()); } } } // Tell client responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusAccountLoginResponse() { MessageID = loginMsg.MessageID, AccountID = account.AccountId, AccountType = MediusAccountType.MediusMasterAccount, ConnectInfo = new NetConnectionInfo() { AccessKey = clientObject.Token, SessionKey = loginMsg.SessionKey, WorldID = Program.Settings.DefaultChannelId, ServerKey = Program.GlobalAuthPublic, AddressList = new NetAddressList() { AddressList = new NetAddress[MediusConstants.NET_ADDRESS_LIST_COUNT] { new NetAddress() { Address = Program.SERVER_IP.ToString(), Port = (uint)Program.LobbyServer.Port, AddressType = NetAddressType.NetAddressTypeExternal }, //new NetAddress() { AddressType = NetAddressType.NetAddressNone} new NetAddress() { Address = Program.SERVER_IP.ToString(), Port = (uint)Program.NATServer.Port, AddressType = NetAddressType.NetAddressTypeNATService }, } }, Type = NetConnectionType.NetConnectionTypeClientServerTCP }, MediusWorldID = Program.Settings.DefaultChannelId, StatusCode = MediusCallbackStatus.MediusSuccess } }); } break; } case MediusAppPacketIds.AccountLogout: { var msg = appMsg as MediusAccountLogoutRequest; bool success = false; // Check token if (client.ClientObject != null && client.ClientObject.ClientAccount != null && msg.SessionKey == client.ClientObject.SessionKey) { success = true; // Logout client.ClientObject.Logout(); } responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusAccountLogoutResponse() { StatusCode = success ? MediusCallbackStatus.MediusSuccess : MediusCallbackStatus.MediusFail } }); break; } case MediusAppPacketIds.TextFilter: { var msg = appMsg as MediusTextFilterRequest; // Accept everything // No filter responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusTextFilterResponse() { MessageID = msg.MessageID, StatusCode = MediusCallbackStatus.MediusSuccess, Text = msg.Text } }); break; } case MediusAppPacketIds.GetBuddyList_ExtraInfo: { var msg = appMsg as MediusGetBuddyList_ExtraInfoRequest; responses.Add(new RT_MSG_SERVER_APP() { AppMessage = new MediusGetBuddyList_ExtraInfoResponse() { MessageID = msg.MessageID, StatusCode = MediusCallbackStatus.MediusNoResult, EndOfList = true } }); break; } case MediusAppPacketIds.Policy: { var policyReq = appMsg as MediusGetPolicyRequest; string policyText = policyReq.Policy == MediusPolicyType.Privacy ? Program.Settings.PrivacyPolicy : Program.Settings.UsagePolicy; responses.AddRange(MediusGetPolicyResponse.FromText(policyReq.MessageID, policyText).Select(x => new RT_MSG_SERVER_APP() { AppMessage = x })); break; } default: { Console.WriteLine($"MAS Unhandled App Message: {appMsg.Id} {appMsg}"); break; } } break; } case RT_MSG_TYPE.RT_MSG_CLIENT_ECHO: { responses.Add(new RT_MSG_CLIENT_ECHO() { Value = (message as RT_MSG_CLIENT_ECHO).Value }); break; } case RT_MSG_TYPE.RT_MSG_CLIENT_DISCONNECT: case RT_MSG_TYPE.RT_MSG_CLIENT_DISCONNECT_WITH_REASON: { client.Disconnect(); break; } } return(0); }