public void Reconnect(RECONNECT msg) { if (Account == null) { string[] labels = new string[] { "{CLIENT_NAME}" }; string[] arguments = new string[] { Account.Name }; SendMessage(new FAILURE { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.LOST_CONNECTION, labels: labels, arguments: arguments ) }); Manager.TryDisconnect(this, DisconnectReason.LOST_CONNECTION); return; } Log.Info($"[({(int)DisconnectReason.RECONNECT}) {DisconnectReason.RECONNECT.ToString()}] Reconnect player '{Account.Name} (Account ID: {Account.AccountId})' to {msg.Name}."); Save(); SendMessage(msg); }
public async void Reconnect(RECONNECT msg) { if (this == null) { return; } if (Account == null) { string[] labels = new string[] { "{CLIENT_NAME}" }; string[] arguments = new string[] { Account.Name }; SendMessage(new FAILURE { ErrorId = Type.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.LOST_CONNECTION, labels: labels, arguments: arguments ) }); await task; Disconnect(DisconnectReason.LOST_CONNECTION); return; } _(Account.AccountId, msg); Save(); await task; task.Dispose(); SendMessage(msg); }
protected override void HandleMessage(Client client, HELLO message) { KeyValuePair <string, bool> versionStatus = Settings.CheckClientVersion(message.BuildVersion); if (!versionStatus.Value) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.OUTDATED_CLIENT, labels: new[] { "{CLIENT_BUILD_VERSION}", "{SERVER_BUILD_VERSION}" }, arguments: new[] { message.BuildVersion, versionStatus.Key } ) }); Manager.TryDisconnect(client, DisconnectReason.OUTDATED_CLIENT); return; } LoginStatus s1 = Manager.Database.Verify(message.GUID, message.Password, out DbAccount acc); if (s1 == LoginStatus.AccountNotExists) { RegisterStatus s2 = Manager.Database.Register(message.GUID, message.Password, true, out acc); //Register guest but do not allow join game. client.SendMessage(new FAILURE() { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.DISABLE_GUEST_ACCOUNT, labels: null, arguments: null ) }); Manager.TryDisconnect(client, DisconnectReason.DISABLE_GUEST_ACCOUNT); return; } else if (s1 == LoginStatus.InvalidCredentials) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.DEFAULT, ErrorDescription = "Bad login." }); Manager.TryDisconnect(client, DisconnectReason.BAD_LOGIN); } client.ConnectedBuild = message.BuildVersion; client.Account = acc; client.AccountId = acc.AccountId; if (AccountInUseManager.ContainsKey(client.AccountId)) { do { double timeout = client.CheckAccountInUseTimeout; if (timeout <= 0) { break; } List <Message> outgoing = new List <Message> { new FAILURE { ErrorId = (int)ErrorIDs.NORMAL_CONNECTION, ErrorDescription = $"Account in use ({timeout:n0} second{(timeout > 1 ? "s" : "")} until timeout)." }, new FAILURE { ErrorId = (int)ErrorIDs.NORMAL_CONNECTION, ErrorDescription = $"Connection failed! Retrying..." } }; client.SendMessage(outgoing); Thread.Sleep(3 * 1000); if (client.CheckAccountInUseTimeout <= 0) { break; } } while (client.Socket.Connected && client.State != ProtocolState.Disconnected); client.RemoveAccountInUse(); } ConnectionProtocol TryConnect = Manager.TryConnect(client); if (!TryConnect.Connected) { ErrorIDs errorID = TryConnect.ErrorID; string[] labels; string[] arguments; DisconnectReason reason; switch (errorID) { case ErrorIDs.SERVER_FULL: { labels = new[] { "{MAX_USAGE}" }; arguments = new[] { Manager.MaxClients.ToString() }; reason = DisconnectReason.SERVER_FULL; } break; case ErrorIDs.ACCOUNT_BANNED: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { acc.Name }; reason = DisconnectReason.ACCOUNT_BANNED; } break; case ErrorIDs.INVALID_DISCONNECT_KEY: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { acc.Name }; reason = DisconnectReason.INVALID_DISCONNECT_KEY; } break; case ErrorIDs.LOST_CONNECTION: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { acc.Name }; reason = DisconnectReason.LOST_CONNECTION; } break; default: { labels = new[] { "{UNKNOW_ERROR_INSTANCE}" }; arguments = new[] { "connection aborted by unexpected protocol at line <b>340</b> or line <b>346</b> from 'TryConnect' function in RealmManager for security reasons" }; reason = DisconnectReason.UNKNOW_ERROR_INSTANCE; } break; } client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: errorID, labels: labels, arguments: arguments ) }); Manager.TryDisconnect(client, reason); return; } else { World world = Manager.GetWorld(message.GameId); if (acc.AccountType == (int)AccountType.VIP_ACCOUNT) { DateTime _currentTime = DateTime.Now; DateTime _vipRegistration = acc.AccountLifetime; if (_vipRegistration <= _currentTime) { acc.AccountType = (int)AccountType.FREE_ACCOUNT; acc.Flush(); acc.Reload(); FAILURE _failure = new FAILURE { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler .FormatedJSONError( errorID: ErrorIDs.VIP_ACCOUNT_OVER, labels: new[] { "{CLIENT_NAME}", "{SERVER_TIME}", "{REGISTRATION_TIME}", "{CURRENT_TIME}" }, arguments: new[] { acc.Name, string.Format(new DateProvider(), "{0}", DateTime.Now), string.Format(new DateProvider(), "{0}", acc.AccountLifetime.AddDays(-30)), string.Format(new DateProvider(), "{0}", acc.AccountLifetime) } ) }; client.SendMessage(_failure); Manager.TryDisconnect(client, DisconnectReason.VIP_ACCOUNT_OVER); return; } } if (world == null) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.DEFAULT, ErrorDescription = "Invalid world." }); Manager.TryDisconnect(client, DisconnectReason.INVALID_WORLD); return; } if (world.NeedsPortalKey) { if (!world.PortalKey.SequenceEqual(message.Key)) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.DEFAULT, ErrorDescription = "Invalid portal key." }); Manager.TryDisconnect(client, DisconnectReason.INVALID_PORTAL_KEY); return; } if (world.PortalKeyExpired) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.DEFAULT, ErrorDescription = "Portal key expired." }); Manager.TryDisconnect(client, DisconnectReason.PORTAL_KEY_EXPIRED); return; } } if (message.MapInfo.Length > 0 || world.Id == -6) { (world as Test).LoadJson(Encoding.Default.GetString(message.MapInfo)); } if (world.IsLimbo) { world = world.GetInstance(client); } client.Random = new wRandom(world.Seed); client.TargetWorld = world.Id; client.SendMessage(new MAPINFO { Width = world.Map.Width, Height = world.Map.Height, Name = world.Name, Seed = world.Seed, ClientWorldName = world.Name, Difficulty = world.Difficulty, Background = world.Background, AllowTeleport = world.AllowTeleport, ShowDisplays = world.ShowDisplays, ClientXML = world.ClientXml, ExtraXML = Manager.GameData.AdditionXml, Music = world.Name }); client.State = ProtocolState.Handshaked; } }
public bool KeepAlive(RealmTime time) { try { if (Client == null) { return(false); } if (_pingTime == -1) { _pingTime = time.TotalElapsedMs - PingPeriod; _pongTime = time.TotalElapsedMs; } if (time.TotalElapsedMs - _pongTime > DcThresold) { string[] labels = new string[] { "{CLIENT_NAME}" }; string[] arguments = new string[] { (Client?.Account?.Name ?? "_null_") }; if (arguments == new string[] { "_null_" }) { return(false); } else { Client?.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.LOST_CONNECTION, labels: labels, arguments: arguments ) }); } return(false); } if (time.TotalElapsedMs - _pingTime < PingPeriod) { return(true); } _pingTime = time.TotalElapsedMs; Client.SendMessage(new PING() { Serial = (int)time.TotalElapsedMs }); return(UpdateOnPing()); } catch (Exception e) { log4net.Info(e); return(false); } }
protected override void HandlePacket(Client client, HELLO packet) { if (SERVER_VERSION != packet.BuildVersion) { client.SendMessage(new FAILURE { ErrorId = 8, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.OUTDATED_CLIENT, labels: new[] { "{CLIENT_BUILD_VERSION}", "{SERVER_BUILD_VERSION}" }, arguments: new[] { packet.BuildVersion, SERVER_VERSION } ) }); client.Disconnect(DisconnectReason.OUTDATED_CLIENT); return; } if (!INTERNAL_SERVER_BUILD.Contains(packet.InternalBuildVersion)) //support for multi internal server build versions { client.SendMessage(new FAILURE { ErrorId = 8, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.OUTDATED_INTERNAL_CLIENT, labels: null, arguments: null ) }); client.Disconnect(DisconnectReason.OUTDATED_INTERNAL_CLIENT); return; } DbAccount acc; LoginStatus s1 = client.Manager.Database.Verify(packet.GUID, packet.Password, out acc); if (s1 == LoginStatus.AccountNotExists) { RegisterStatus s2 = client.Manager.Database.Register(packet.GUID, packet.Password, true, out acc); //Register guest but do not allow join game. client.SendMessage(new FAILURE() { ErrorId = 8, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.DISABLE_GUEST_ACCOUNT, labels: null, arguments: null ) }); client.Disconnect(DisconnectReason.DISABLE_GUEST_ACCOUNT); return; } else if (s1 == LoginStatus.InvalidCredentials) { client.SendMessage(new FAILURE { ErrorId = 0, ErrorDescription = "Bad login." }); client.Disconnect(DisconnectReason.BAD_LOGIN); } client.ConnectedBuild = packet.BuildVersion; Tuple <bool, ErrorIDs> TryConnect = client.Manager.TryConnect(client); if (!TryConnect.Item1) { client.Account = null; ErrorIDs errorID = TryConnect.Item2; string[] labels; string[] arguments; DisconnectReason type; switch (TryConnect.Item2) { case ErrorIDs.SERVER_FULL: { labels = new[] { "{MAX_USAGE}" }; arguments = new[] { $"{client.Manager.MaxClients}" }; type = DisconnectReason.SERVER_FULL; } break; case ErrorIDs.ACCOUNT_BANNED: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { client.Account.Name }; type = DisconnectReason.ACCOUNT_BANNED; } break; case ErrorIDs.INVALID_DISCONNECT_KEY: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { client.Account.Name }; type = DisconnectReason.INVALID_DISCONNECT_KEY; } break; case ErrorIDs.LOST_CONNECTION: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { client.Account.Name }; type = DisconnectReason.LOST_CONNECTION; } break; default: { labels = new[] { "{UNKNOW_ERROR_INSTANCE}" }; arguments = new[] { "connection aborted by unexpected protocol at line <b>340</b> or line <b>346</b> from 'TryConnect' function in RealmManager for security reasons" }; type = DisconnectReason.UNKNOW_ERROR_INSTANCE; } break; } client.SendMessage(new FAILURE { ErrorId = 8, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: errorID, labels: labels, arguments: arguments ) }); client.Disconnect(type); return; } else { if (packet.GameId == World.NEXUS_LIMBO) { packet.GameId = World.NEXUS_ID; } World world = client.Manager.GetWorld(packet.GameId); if (world == null && packet.GameId == World.TUT_ID) { world = client.Manager.AddWorld(new Tutorial(false)); } if (!client.Manager.Database.AcquireLock(acc)) { //SendFailure(client, "Account in Use (" + // client.Manager.Database.GetLockTime(acc) + " seconds until timeout)"); client.Disconnect(DisconnectReason.ACCOUNT_IN_USE); return; } if (world == null) { client.SendMessage(new FAILURE { ErrorId = 1, ErrorDescription = "Invalid world." }); client.Disconnect(DisconnectReason.INVALID_WORLD); return; } if (world.NeedsPortalKey) { if (!world.PortalKey.SequenceEqual(packet.Key)) { client.SendMessage(new FAILURE { ErrorId = 1, ErrorDescription = "Invalid Portal Key" }); client.Disconnect(DisconnectReason.INVALID_PORTAL_KEY); return; } if (world.PortalKeyExpired) { client.SendMessage(new FAILURE { ErrorId = 1, ErrorDescription = "Portal key expired." }); client.Disconnect(DisconnectReason.PORTAL_KEY_EXPIRED); return; } } if (packet.MapInfo.Length > 0 || world.Id == -6) //Test World { (world as Test).LoadJson(Encoding.Default.GetString(packet.MapInfo)); } if (world.IsLimbo) { world = world.GetInstance(client); } client.Account = acc; client.Random = new wRandom(world.Seed); client.TargetWorld = world.Id; client.SendMessage(new MAPINFO { Width = world.Map.Width, Height = world.Map.Height, Name = world.Name, Seed = world.Seed, ClientWorldName = world.ClientWorldName, Difficulty = world.Difficulty, Background = world.Background, AllowTeleport = world.AllowTeleport, ShowDisplays = world.ShowDisplays, ClientXML = world.ClientXml, ExtraXML = Manager.GameData.AdditionXml, Music = world.Name }); client.State = ProtocolState.Handshaked; } }
protected override void HandleMessage(Client client, HELLO message) { var versionStatus = Settings.CheckClientVersion(message.BuildVersion); if (!versionStatus.Value) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.OUTDATED_CLIENT, labels: new[] { "{CLIENT_BUILD_VERSION}", "{SERVER_BUILD_VERSION}" }, arguments: new[] { message.BuildVersion, versionStatus.Key } ) }); GameServer.Manager.TryDisconnect(client, DisconnectReason.OUTDATED_CLIENT); return; } var s1 = GameServer.Manager.Database.Verify(message.GUID, message.Password, out DbAccount acc); if (s1 == LoginStatus.AccountNotExists) { var s2 = GameServer.Manager.Database.Register(message.GUID, message.Password, true, out acc); //Register guest but do not allow join game. client.SendMessage(new FAILURE() { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: ErrorIDs.DISABLE_GUEST_ACCOUNT, labels: null, arguments: null ) }); GameServer.Manager.TryDisconnect(client, DisconnectReason.DISABLE_GUEST_ACCOUNT); return; } else if (s1 == LoginStatus.InvalidCredentials) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.DEFAULT, ErrorDescription = "Bad login." }); GameServer.Manager.TryDisconnect(client, DisconnectReason.BAD_LOGIN); } client.ConnectedBuild = message.BuildVersion; client.Account = acc; client.AccountId = acc.AccountId; var TryConnect = GameServer.Manager.TryConnect(client); if (!TryConnect.Connected) { var errorID = TryConnect.ErrorID; string[] labels; string[] arguments; DisconnectReason reason; switch (errorID) { case ErrorIDs.SERVER_FULL: { labels = new[] { "{MAX_USAGE}" }; arguments = new[] { GameServer.Manager.MaxClients.ToString() }; reason = DisconnectReason.SERVER_FULL; } break; case ErrorIDs.ACCOUNT_BANNED: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { acc.Name }; reason = DisconnectReason.ACCOUNT_BANNED; } break; case ErrorIDs.INVALID_DISCONNECT_KEY: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { acc.Name }; reason = DisconnectReason.INVALID_DISCONNECT_KEY; } break; case ErrorIDs.LOST_CONNECTION: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { acc.Name }; reason = DisconnectReason.LOST_CONNECTION; } break; case ErrorIDs.ACCESS_DENIED_DUE_RESTART: { labels = new[] { "{CLIENT_NAME}" }; arguments = new[] { acc.Name }; reason = DisconnectReason.ACCESS_DENIED_DUE_RESTART; } break; default: { labels = new[] { "{UNKNOW_ERROR_INSTANCE}" }; arguments = new[] { "connection aborted by unexpected protocol at line <b>340</b> or line <b>346</b> from 'TryConnect' function in RealmManager for security reasons" }; reason = DisconnectReason.UNKNOW_ERROR_INSTANCE; } break; } client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler. FormatedJSONError( errorID: errorID, labels: labels, arguments: arguments ) }); GameServer.Manager.TryDisconnect(client, reason); return; } else { var world = GameServer.Manager.GetWorld(message.GameId); if (world == null) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.DEFAULT, ErrorDescription = "Invalid world." }); GameServer.Manager.TryDisconnect(client, DisconnectReason.INVALID_WORLD); return; } if (world.NeedsPortalKey) { if (!world.PortalKey.SequenceEqual(message.Key)) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.DEFAULT, ErrorDescription = "Invalid portal key." }); GameServer.Manager.TryDisconnect(client, DisconnectReason.INVALID_PORTAL_KEY); return; } if (world.PortalKeyExpired) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.DEFAULT, ErrorDescription = "Portal key expired." }); GameServer.Manager.TryDisconnect(client, DisconnectReason.PORTAL_KEY_EXPIRED); return; } } if (acc.AccountType == (int)AccountType.VIP) { var _currentTime = DateTime.UtcNow; var _vipRegistration = acc.AccountLifetime; if (_vipRegistration <= _currentTime) { acc.AccountType = (int)AccountType.REGULAR; acc.FlushAsync(); acc.Reload(); var _failure = new FAILURE { ErrorId = (int)FailureIDs.JSON_DIALOG, ErrorDescription = JSONErrorIDHandler .FormatedJSONError( errorID: ErrorIDs.VIP_ACCOUNT_OVER, labels: new[] { "{CLIENT_NAME}", "{SERVER_TIME}", "{REGISTRATION_TIME}", "{CURRENT_TIME}" }, arguments: new[] { acc.Name, string.Format(new DateProvider(), "{0}", DateTime.UtcNow), string.Format(new DateProvider(), "{0}", acc.AccountLifetime.AddDays(-30)), string.Format(new DateProvider(), "{0}", acc.AccountLifetime) } ) }; client.SendMessage(_failure); GameServer.Manager.TryDisconnect(client, DisconnectReason.VIP_ACCOUNT_OVER); return; } } if (message.MapInfo.Length > 0 || world.Id == -6) { client.SendMessage(new FAILURE { ErrorId = (int)FailureIDs.DEFAULT, ErrorDescription = "Test map feature isn't working..." }); GameServer.Manager.TryDisconnect(client, DisconnectReason.TEST_MAP_NOT_ADDED); return; } if (world.IsLimbo) { world = world.GetInstance(client); } client.Random = new wRandom(world.Seed); client.TargetWorld = world.Id; client.SendMessage(new MAPINFO { Width = world.Map.Width, Height = world.Map.Height, Name = world.Name, Seed = world.Seed, ClientWorldName = world.Name, Difficulty = world.Difficulty, Background = world.Background, AllowTeleport = world.AllowTeleport, ShowDisplays = world.ShowDisplays, ClientXML = world.ClientXml, ExtraXML = GameServer.Manager.GameData.AdditionXml, Music = world.Name }); client.State = ProtocolState.Handshaked; } }