コード例 #1
0
        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;
            }
            }
        }
コード例 #2
0
        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);
        }