From 77af7d6b0f6268e012311a0df2d052fda04409f9 Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Mon, 29 Oct 2018 21:28:49 +0800 Subject: [PATCH 01/11] Initial subsystem, add login attempt and spawn event handler --- TShockAPI/GetDataHandlers.cs | 115 ++++++++++++++++++++--------------- TShockAPI/SSC.cs | 95 +++++++++++++++++++++++++++++ TShockAPI/TShock.cs | 7 +++ TShockAPI/TShockAPI.csproj | 1 + 4 files changed, 170 insertions(+), 48 deletions(-) create mode 100644 TShockAPI/SSC.cs diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 4a126d567..6fde682e2 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -265,6 +265,25 @@ private static bool OnPlayerSlot(TSPlayer player, MemoryStream data, byte _plr, return args.Handled; } + /// + /// Connecting - called at a Connecting event + /// + public static HandlerList Connecting = new HandlerList(); + private static bool OnConnecting(TSPlayer player, MemoryStream data) + { + if (Connecting == null) + return false; + + var args = new GetDataHandledEventArgs + { + Player = player, + + Data = data + }; + Connecting.Invoke(null, args); + return args.Handled; + } + /// The arguments to a GetSection packet. public class GetSectionEventArgs : GetDataHandledEventArgs { @@ -936,6 +955,35 @@ private static bool OnPlayerZone(TSPlayer player, MemoryStream data, byte plr, B PlayerZone.Invoke(null, args); return args.Handled; } + + /// + /// For use in a Password Event + /// + public class PasswordEventArgs : GetDataHandledEventArgs + { + /// + /// The Password + /// + public string Password { get; set; } + } + /// + /// Password - When clients send password to server + /// + public static HandlerList Password = new HandlerList(); + private static bool OnPassword(TSPlayer player, MemoryStream data, string password) + { + if (Password == null) + return false; + + var args = new PasswordEventArgs + { + Player = player, + Data = data, + Password = password + }; + Password.Invoke(null, args); + return args.Handled; + } /// /// For use with a PlayerAnimation event @@ -1944,15 +1992,8 @@ private static bool HandleConnecting(GetDataHandlerArgs args) args.Player.IsLoggedIn = true; args.Player.IsDisabledForSSC = false; - if (Main.ServerSideCharacter) - { - if (args.Player.HasPermission(Permissions.bypassssc)) - { - args.Player.PlayerData.CopyCharacter(args.Player); - TShock.CharacterDB.InsertPlayerData(args.Player); - } - args.Player.PlayerData.RestoreCharacter(args.Player); - } + if (OnConnecting(args.Player, args.Data)) + return true; args.Player.LoginFailsBySsi = false; if (args.Player.HasPermission(Permissions.ignorestackhackdetection)) @@ -2010,23 +2051,7 @@ private static bool HandleSpawn(GetDataHandlerArgs args) if (OnPlayerSpawn(args.Player, args.Data, player, spawnx, spawny)) return true; - - if ((Main.ServerSideCharacter) && (args.Player.sX > 0) && (args.Player.sY > 0) && (args.TPlayer.SpawnX > 0) && ((args.TPlayer.SpawnX != args.Player.sX) && (args.TPlayer.SpawnY != args.Player.sY))) - { - - args.Player.sX = args.TPlayer.SpawnX; - args.Player.sY = args.TPlayer.SpawnY; - - if (((Main.tile[args.Player.sX, args.Player.sY - 1].active() && Main.tile[args.Player.sX, args.Player.sY - 1].type == 79)) && (WorldGen.StartRoomCheck(args.Player.sX, args.Player.sY - 1))) - args.Player.Teleport(args.Player.sX * 16, (args.Player.sY * 16) - 48); - } - - else if ((Main.ServerSideCharacter) && (args.Player.sX > 0) && (args.Player.sY > 0)) - { - if (((Main.tile[args.Player.sX, args.Player.sY - 1].active() && Main.tile[args.Player.sX, args.Player.sY - 1].type == 79)) && (WorldGen.StartRoomCheck(args.Player.sX, args.Player.sY - 1))) - args.Player.Teleport(args.Player.sX * 16, (args.Player.sY * 16) - 48); - } - + args.Player.Dead = false; return false; } @@ -2513,31 +2538,25 @@ private static bool HandlePassword(GetDataHandlerArgs args) args.Player.tempGroup = null; args.Player.Account = account; args.Player.IsLoggedIn = true; - args.Player.IsDisabledForSSC = false; - if (Main.ServerSideCharacter) + if (OnPassword(args.Player, args.Data, password)) { - if (args.Player.HasPermission(Permissions.bypassssc)) - { - args.Player.PlayerData.CopyCharacter(args.Player); - TShock.CharacterDB.InsertPlayerData(args.Player); - } - args.Player.PlayerData.RestoreCharacter(args.Player); + return true; + } + else + { + if (args.Player.HasPermission(Permissions.ignorestackhackdetection)) + args.Player.IsDisabledForStackDetection = false; + + if (args.Player.HasPermission(Permissions.usebanneditem)) + args.Player.IsDisabledForBannedWearable = false; + + args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen); + TShock.Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + "."); + TShock.UserAccounts.SetUserAccountUUID(account, args.Player.UUID); + Hooks.PlayerHooks.OnPlayerPostLogin(args.Player); + return true; } - args.Player.LoginFailsBySsi = false; - - if (args.Player.HasPermission(Permissions.ignorestackhackdetection)) - args.Player.IsDisabledForStackDetection = false; - - if (args.Player.HasPermission(Permissions.usebanneditem)) - args.Player.IsDisabledForBannedWearable = false; - - - args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen); - TShock.Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + "."); - TShock.UserAccounts.SetUserAccountUUID(account, args.Player.UUID); - Hooks.PlayerHooks.OnPlayerPostLogin(args.Player); - return true; } args.Player.Kick("Your password did not match this character's password.", true, true); return true; diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs new file mode 100644 index 000000000..b8f4a0b34 --- /dev/null +++ b/TShockAPI/SSC.cs @@ -0,0 +1,95 @@ +/* +TShock, a server mod for Terraria +Copyright (C) 2011-2018 Pryaxis & TShock Contributors + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using Terraria.ID; +using TShockAPI.DB; +using TShockAPI.Net; +using Terraria; +using Microsoft.Xna.Framework; +using OTAPI.Tile; +using TShockAPI.Localization; +using static TShockAPI.GetDataHandlers; +using TerrariaApi.Server; +using Terraria.ObjectData; +using Terraria.DataStructures; +using Terraria.Localization; + +namespace TShockAPI +{ + /// The TShock server side character subsystem. + internal sealed class SSC + { + /// A reference to the TShock plugin so we can register events. + private TShock Plugin; + + /// A new SSC system. + internal SSC() + { + // Setup Handlers + GetDataHandlers.Connecting += Login; + GetDataHandlers.PlayerSpawn += OnSpawn; + GetDataHandlers.Password += Login; + } + + internal void Login(object sender, GetDataHandledEventArgs args) + { + try + { + args.Player.IsDisabledForSSC = false; + + if (args.Player.HasPermission(Permissions.bypassssc)) + { + args.Player.PlayerData.CopyCharacter(args.Player); + TShock.CharacterDB.InsertPlayerData(args.Player); + } + args.Player.PlayerData.RestoreCharacter(args.Player); + args.Player.LoginFailsBySsi = false; + } + catch(Exception ex) + { + TShock.Log.ConsoleError(ex.ToString()); + + args.Player.IsDisabledForSSC = true; + args.Player.LoginFailsBySsi = true; + } + } + + internal void OnSpawn(object sender, SpawnEventArgs args) + { + var p = args.Player; + if ((p.sX > 0) && (p.sY > 0) && (p.TPlayer.SpawnX > 0) && + ((p.TPlayer.SpawnX != p.sX) && (p.TPlayer.SpawnY != p.sY))) + { + + p.sX = p.TPlayer.SpawnX; + p.sY = p.TPlayer.SpawnY; + + if (((Main.tile[p.sX, p.sY - 1].active() && Main.tile[p.sX, p.sY - 1].type == 79)) && (WorldGen.StartRoomCheck(p.sX, p.sY - 1))) + p.Teleport(p.sX * 16, (p.sY * 16) - 48); + } + + else if ((p.sX > 0) && (p.sY > 0)) + { + if (((Main.tile[p.sX, p.sY - 1].active() && Main.tile[p.sX, p.sY - 1].type == 79)) && (WorldGen.StartRoomCheck(p.sX, p.sY - 1))) + p.Teleport(p.sX * 16, (p.sY * 16) - 48); + } + } + } +} diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index f839019d6..77aa47260 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -139,6 +139,11 @@ public class TShock : TerrariaPlugin /// internal RegionHandler RegionSystem; + /// + /// TShock's SSC subsystem. + /// + internal SSC SSC; + /// /// Called after TShock is initialized. Useful for plugins that needs hooks before tshock but also depend on tshock being loaded. /// @@ -325,6 +330,8 @@ public override void Initialize() RestManager.RegisterRestfulCommands(); Bouncer = new Bouncer(); RegionSystem = new RegionHandler(Regions); + if(Main.ServerSideCharacter) + SSC = new SSC(); var geoippath = "GeoIP.dat"; if (Config.EnableGeoIP && File.Exists(geoippath)) diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index b3deaaeaf..a76a2aeda 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -97,6 +97,7 @@ + From 6ae1dcb5a10734ef93f53dd5a02f7b960d5877b9 Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Mon, 29 Oct 2018 21:39:37 +0800 Subject: [PATCH 02/11] Remove ssc related things in HandleConnecting and move successfully login stuff --- TShockAPI/GetDataHandlers.cs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 6fde682e2..f702f3148 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1990,22 +1990,24 @@ private static bool HandleConnecting(GetDataHandlerArgs args) args.Player.tempGroup = null; args.Player.Account = account; args.Player.IsLoggedIn = true; - args.Player.IsDisabledForSSC = false; if (OnConnecting(args.Player, args.Data)) + { return true; - args.Player.LoginFailsBySsi = false; - - if (args.Player.HasPermission(Permissions.ignorestackhackdetection)) - args.Player.IsDisabledForStackDetection = false; + } + else + { + if (args.Player.HasPermission(Permissions.ignorestackhackdetection)) + args.Player.IsDisabledForStackDetection = false; - if (args.Player.HasPermission(Permissions.usebanneditem)) - args.Player.IsDisabledForBannedWearable = false; + if (args.Player.HasPermission(Permissions.usebanneditem)) + args.Player.IsDisabledForBannedWearable = false; - args.Player.SendSuccessMessage("Authenticated as " + account.Name + " successfully."); - TShock.Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + "."); - Hooks.PlayerHooks.OnPlayerPostLogin(args.Player); - return true; + args.Player.SendSuccessMessage("Authenticated as " + account.Name + " successfully."); + TShock.Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + "."); + Hooks.PlayerHooks.OnPlayerPostLogin(args.Player); + return true; + } } } else if (account != null && !TShock.Config.DisableLoginBeforeJoin) From e35ec1b24de69a2204825395ab0ae6b82dbefd6d Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Mon, 29 Oct 2018 21:44:40 +0800 Subject: [PATCH 03/11] Add PlayerSlot event handler --- TShockAPI/GetDataHandlers.cs | 5 ----- TShockAPI/SSC.cs | 10 ++++++++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index f702f3148..d15b38637 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1937,11 +1937,6 @@ private static bool HandlePlayerSlot(GetDataHandlerArgs args) if (OnPlayerSlot(args.Player, args.Data, plr, slot, stack, prefix, type) || plr != args.Player.Index || slot < 0 || slot > NetItem.MaxInventory) return true; - if (args.Player.IgnoreSSCPackets) - { - args.Player.SendData(PacketTypes.PlayerSlot, "", args.Player.Index, slot, prefix); - return true; - } // Garabage? Or will it cause some internal initialization or whatever? var item = new Item(); diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs index b8f4a0b34..c00c7e842 100644 --- a/TShockAPI/SSC.cs +++ b/TShockAPI/SSC.cs @@ -43,11 +43,21 @@ internal sealed class SSC internal SSC() { // Setup Handlers + GetDataHandlers.PlayerSlot += Login; GetDataHandlers.Connecting += Login; GetDataHandlers.PlayerSpawn += OnSpawn; GetDataHandlers.Password += Login; } + internal void OnPlayerSlot(object sender, PlayerSlotEventArgs args) + { + if (args.Player.IgnoreSSCPackets) + { + args.Player.SendData(PacketTypes.PlayerSlot, "", args.Player.Index, args.Slot, args.Prefix); + args.Handled = true; + } + } + internal void Login(object sender, GetDataHandledEventArgs args) { try From 0f8546f51c57655e055050556b6ab74ba890d266 Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Mon, 29 Oct 2018 21:45:09 +0800 Subject: [PATCH 04/11] Revert "Add PlayerSlot event handler" This reverts commit e35ec1b24de69a2204825395ab0ae6b82dbefd6d. --- TShockAPI/GetDataHandlers.cs | 5 +++++ TShockAPI/SSC.cs | 10 ---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index d15b38637..f702f3148 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1937,6 +1937,11 @@ private static bool HandlePlayerSlot(GetDataHandlerArgs args) if (OnPlayerSlot(args.Player, args.Data, plr, slot, stack, prefix, type) || plr != args.Player.Index || slot < 0 || slot > NetItem.MaxInventory) return true; + if (args.Player.IgnoreSSCPackets) + { + args.Player.SendData(PacketTypes.PlayerSlot, "", args.Player.Index, slot, prefix); + return true; + } // Garabage? Or will it cause some internal initialization or whatever? var item = new Item(); diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs index c00c7e842..b8f4a0b34 100644 --- a/TShockAPI/SSC.cs +++ b/TShockAPI/SSC.cs @@ -43,21 +43,11 @@ internal sealed class SSC internal SSC() { // Setup Handlers - GetDataHandlers.PlayerSlot += Login; GetDataHandlers.Connecting += Login; GetDataHandlers.PlayerSpawn += OnSpawn; GetDataHandlers.Password += Login; } - internal void OnPlayerSlot(object sender, PlayerSlotEventArgs args) - { - if (args.Player.IgnoreSSCPackets) - { - args.Player.SendData(PacketTypes.PlayerSlot, "", args.Player.Index, args.Slot, args.Prefix); - args.Handled = true; - } - } - internal void Login(object sender, GetDataHandledEventArgs args) { try From 9ba01d5a81be168acc3449cce3e1eaa731fc5fc1 Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Mon, 29 Oct 2018 21:49:31 +0800 Subject: [PATCH 05/11] Add PlayerUpdate handler --- TShockAPI/GetDataHandlers.cs | 31 +------------------------------ TShockAPI/SSC.cs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index f702f3148..13486089e 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -2165,36 +2165,7 @@ private static bool HandlePlayerUpdate(GetDataHandlerArgs args) { args.TPlayer.direction = -1; } - - if (args.Player.Confused && Main.ServerSideCharacter && args.Player.IsLoggedIn) - { - if (args.TPlayer.controlUp) - { - args.TPlayer.controlDown = true; - args.TPlayer.controlUp = false; - } - else if (args.TPlayer.controlDown) - { - args.TPlayer.controlDown = false; - args.TPlayer.controlUp = true; - } - - if (args.TPlayer.controlLeft) - { - args.TPlayer.controlRight = true; - args.TPlayer.controlLeft = false; - } - else if (args.TPlayer.controlRight) - { - args.TPlayer.controlRight = false; - args.TPlayer.controlLeft = true; - } - - args.TPlayer.Update(args.TPlayer.whoAmI); - NetMessage.SendData((int)PacketTypes.PlayerUpdate, -1, -1, NetworkText.Empty, args.Player.Index); - return true; - } - + NetMessage.SendData((int)PacketTypes.PlayerUpdate, -1, args.Player.Index, NetworkText.Empty, args.Player.Index); return true; } diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs index b8f4a0b34..6ef61bfcb 100644 --- a/TShockAPI/SSC.cs +++ b/TShockAPI/SSC.cs @@ -45,9 +45,43 @@ internal SSC() // Setup Handlers GetDataHandlers.Connecting += Login; GetDataHandlers.PlayerSpawn += OnSpawn; + GetDataHandlers.PlayerUpdate += OnPlayerUpdate; GetDataHandlers.Password += Login; } + internal void OnPlayerUpdate(object sender, PlayerUpdateEventArgs args) + { + var tplr = args.Player.TPlayer; + if (args.Player.Confused && Main.ServerSideCharacter && args.Player.IsLoggedIn) + { + if (tplr.controlUp) + { + tplr.controlDown = true; + tplr.controlUp = false; + } + else if (tplr.controlDown) + { + tplr.controlDown = false; + tplr.controlUp = true; + } + + if (tplr.controlLeft) + { + tplr.controlRight = true; + tplr.controlLeft = false; + } + else if (tplr.controlRight) + { + tplr.controlRight = false; + tplr.controlLeft = true; + } + + tplr.Update(tplr.whoAmI); + NetMessage.SendData((int)PacketTypes.PlayerUpdate, -1, -1, NetworkText.Empty, args.Player.Index); + args.Handled = true; + } + } + internal void Login(object sender, GetDataHandledEventArgs args) { try From 92fe16ab52963e78b8f6cde795ec119a36a5abe7 Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Mon, 29 Oct 2018 21:53:21 +0800 Subject: [PATCH 06/11] Add KillMe handler --- TShockAPI/GetDataHandlers.cs | 9 ---- TShockAPI/SSC.cs | 79 +++++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 13486089e..5c75eb6b3 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -3311,15 +3311,6 @@ private static bool HandlePlayerKillMeV2(GetDataHandlerArgs args) } } - if (args.TPlayer.difficulty == 2 && Main.ServerSideCharacter && args.Player.IsLoggedIn) - { - if (TShock.CharacterDB.RemovePlayer(args.Player.Account.ID)) - { - args.Player.SendErrorMessage("You have fallen in hardcore mode, and your items have been lost forever."); - TShock.CharacterDB.SeedInitialData(args.Player.Account); - } - } - return false; } diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs index 6ef61bfcb..cef101b27 100644 --- a/TShockAPI/SSC.cs +++ b/TShockAPI/SSC.cs @@ -47,39 +47,7 @@ internal SSC() GetDataHandlers.PlayerSpawn += OnSpawn; GetDataHandlers.PlayerUpdate += OnPlayerUpdate; GetDataHandlers.Password += Login; - } - - internal void OnPlayerUpdate(object sender, PlayerUpdateEventArgs args) - { - var tplr = args.Player.TPlayer; - if (args.Player.Confused && Main.ServerSideCharacter && args.Player.IsLoggedIn) - { - if (tplr.controlUp) - { - tplr.controlDown = true; - tplr.controlUp = false; - } - else if (tplr.controlDown) - { - tplr.controlDown = false; - tplr.controlUp = true; - } - - if (tplr.controlLeft) - { - tplr.controlRight = true; - tplr.controlLeft = false; - } - else if (tplr.controlRight) - { - tplr.controlRight = false; - tplr.controlLeft = true; - } - - tplr.Update(tplr.whoAmI); - NetMessage.SendData((int)PacketTypes.PlayerUpdate, -1, -1, NetworkText.Empty, args.Player.Index); - args.Handled = true; - } + GetDataHandlers.KillMe += OnKillMe; } internal void Login(object sender, GetDataHandledEventArgs args) @@ -125,5 +93,50 @@ internal void OnSpawn(object sender, SpawnEventArgs args) p.Teleport(p.sX * 16, (p.sY * 16) - 48); } } + + internal void OnPlayerUpdate(object sender, PlayerUpdateEventArgs args) + { + var tplr = args.Player.TPlayer; + if (args.Player.Confused && args.Player.IsLoggedIn) + { + if (tplr.controlUp) + { + tplr.controlDown = true; + tplr.controlUp = false; + } + else if (tplr.controlDown) + { + tplr.controlDown = false; + tplr.controlUp = true; + } + + if (tplr.controlLeft) + { + tplr.controlRight = true; + tplr.controlLeft = false; + } + else if (tplr.controlRight) + { + tplr.controlRight = false; + tplr.controlLeft = true; + } + + tplr.Update(tplr.whoAmI); + NetMessage.SendData((int)PacketTypes.PlayerUpdate, -1, -1, NetworkText.Empty, args.Player.Index); + args.Handled = true; + } + } + + internal void OnKillMe(object sender, KillMeEventArgs args) + { + if (args.Player.TPlayer.difficulty == 2 && args.Player.IsLoggedIn) + { + if (TShock.CharacterDB.RemovePlayer(args.Player.Account.ID)) + { + args.Player.SendErrorMessage("You have fallen in hardcore mode, and your items have been lost forever."); + TShock.CharacterDB.SeedInitialData(args.Player.Account); + } + } + } } } From f9632781a8f2029ebf12e7840d988daf65e9db5a Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Mon, 29 Oct 2018 22:00:36 +0800 Subject: [PATCH 07/11] Add GameUpdate hook handler(SSC save) --- TShockAPI/SSC.cs | 20 ++++++++++++++++++++ TShockAPI/TShock.cs | 18 ++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs index cef101b27..ae6ff29c0 100644 --- a/TShockAPI/SSC.cs +++ b/TShockAPI/SSC.cs @@ -48,6 +48,9 @@ internal SSC() GetDataHandlers.PlayerUpdate += OnPlayerUpdate; GetDataHandlers.Password += Login; GetDataHandlers.KillMe += OnKillMe; + + // Setup hooks + ServerApi.Hooks.GameUpdate.Register(Plugin, OnGameUpdate); } internal void Login(object sender, GetDataHandledEventArgs args) @@ -138,5 +141,22 @@ internal void OnKillMe(object sender, KillMeEventArgs args) } } } + + internal void OnGameUpdate(EventArgs args) + { + if ((DateTime.UtcNow - Plugin.LastSave).TotalMinutes >= TShock.ServerSideCharacterConfig.ServerSideCharacterSave) + { + foreach (TSPlayer player in TShock.Players) + { + // prevent null point exceptions + if (player != null && player.IsLoggedIn && !player.IsDisabledPendingTrashRemoval) + { + + TShock.CharacterDB.InsertPlayerData(player); + } + } + Plugin.LastSave = DateTime.UtcNow; + } + } } } diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 77aa47260..476995bb0 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -904,10 +904,10 @@ private void OnPostInit(EventArgs args) } /// LastCheck - Used to keep track of the last check for basically all time based checks. - private DateTime LastCheck = DateTime.UtcNow; + internal DateTime LastCheck = DateTime.UtcNow; /// LastSave - Used to keep track of SSC save intervals. - private DateTime LastSave = DateTime.UtcNow; + internal DateTime LastSave = DateTime.UtcNow; /// OnUpdate - Called when ever the server ticks. /// args - EventArgs args @@ -921,20 +921,6 @@ private void OnUpdate(EventArgs args) OnSecondUpdate(); LastCheck = DateTime.UtcNow; } - - if (Main.ServerSideCharacter && (DateTime.UtcNow - LastSave).TotalMinutes >= ServerSideCharacterConfig.ServerSideCharacterSave) - { - foreach (TSPlayer player in Players) - { - // prevent null point exceptions - if (player != null && player.IsLoggedIn && !player.IsDisabledPendingTrashRemoval) - { - - CharacterDB.InsertPlayerData(player); - } - } - LastSave = DateTime.UtcNow; - } } /// OnSecondUpdate - Called effectively every second for all time based checks. From 00b87b58d84cf985f5cdc23f3e8e573f5ebe81fc Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Mon, 29 Oct 2018 22:37:41 +0800 Subject: [PATCH 08/11] Add NetGreetPlayer and ServerLeave hook handler --- TShockAPI/SSC.cs | 55 ++++++++++++++++++++++++++++++++++++++------- TShockAPI/TShock.cs | 8 +------ 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs index ae6ff29c0..510c0688a 100644 --- a/TShockAPI/SSC.cs +++ b/TShockAPI/SSC.cs @@ -42,15 +42,17 @@ internal sealed class SSC /// A new SSC system. internal SSC() { - // Setup Handlers + // Setup GetDataHandlers GetDataHandlers.Connecting += Login; GetDataHandlers.PlayerSpawn += OnSpawn; GetDataHandlers.PlayerUpdate += OnPlayerUpdate; GetDataHandlers.Password += Login; GetDataHandlers.KillMe += OnKillMe; - // Setup hooks + // Setup ServerApi Hook Handler ServerApi.Hooks.GameUpdate.Register(Plugin, OnGameUpdate); + ServerApi.Hooks.NetGreetPlayer.Register(Plugin, OnGreetPlayer); + ServerApi.Hooks.ServerLeave.Register(Plugin, OnLeave); } internal void Login(object sender, GetDataHandledEventArgs args) @@ -64,10 +66,11 @@ internal void Login(object sender, GetDataHandledEventArgs args) args.Player.PlayerData.CopyCharacter(args.Player); TShock.CharacterDB.InsertPlayerData(args.Player); } + args.Player.PlayerData.RestoreCharacter(args.Player); args.Player.LoginFailsBySsi = false; } - catch(Exception ex) + catch (Exception ex) { TShock.Log.ConsoleError(ex.ToString()); @@ -86,13 +89,15 @@ internal void OnSpawn(object sender, SpawnEventArgs args) p.sX = p.TPlayer.SpawnX; p.sY = p.TPlayer.SpawnY; - if (((Main.tile[p.sX, p.sY - 1].active() && Main.tile[p.sX, p.sY - 1].type == 79)) && (WorldGen.StartRoomCheck(p.sX, p.sY - 1))) + if (((Main.tile[p.sX, p.sY - 1].active() && Main.tile[p.sX, p.sY - 1].type == 79)) && + (WorldGen.StartRoomCheck(p.sX, p.sY - 1))) p.Teleport(p.sX * 16, (p.sY * 16) - 48); } else if ((p.sX > 0) && (p.sY > 0)) { - if (((Main.tile[p.sX, p.sY - 1].active() && Main.tile[p.sX, p.sY - 1].type == 79)) && (WorldGen.StartRoomCheck(p.sX, p.sY - 1))) + if (((Main.tile[p.sX, p.sY - 1].active() && Main.tile[p.sX, p.sY - 1].type == 79)) && + (WorldGen.StartRoomCheck(p.sX, p.sY - 1))) p.Teleport(p.sX * 16, (p.sY * 16) - 48); } } @@ -125,7 +130,7 @@ internal void OnPlayerUpdate(object sender, PlayerUpdateEventArgs args) } tplr.Update(tplr.whoAmI); - NetMessage.SendData((int)PacketTypes.PlayerUpdate, -1, -1, NetworkText.Empty, args.Player.Index); + NetMessage.SendData((int) PacketTypes.PlayerUpdate, -1, -1, NetworkText.Empty, args.Player.Index); args.Handled = true; } } @@ -136,7 +141,8 @@ internal void OnKillMe(object sender, KillMeEventArgs args) { if (TShock.CharacterDB.RemovePlayer(args.Player.Account.ID)) { - args.Player.SendErrorMessage("You have fallen in hardcore mode, and your items have been lost forever."); + args.Player.SendErrorMessage( + "You have fallen in hardcore mode, and your items have been lost forever."); TShock.CharacterDB.SeedInitialData(args.Player.Account); } } @@ -144,7 +150,8 @@ internal void OnKillMe(object sender, KillMeEventArgs args) internal void OnGameUpdate(EventArgs args) { - if ((DateTime.UtcNow - Plugin.LastSave).TotalMinutes >= TShock.ServerSideCharacterConfig.ServerSideCharacterSave) + if ((DateTime.UtcNow - Plugin.LastSave).TotalMinutes >= + TShock.ServerSideCharacterConfig.ServerSideCharacterSave) { foreach (TSPlayer player in TShock.Players) { @@ -155,8 +162,40 @@ internal void OnGameUpdate(EventArgs args) TShock.CharacterDB.InsertPlayerData(player); } } + Plugin.LastSave = DateTime.UtcNow; } } + + internal void OnGreetPlayer(GreetPlayerEventArgs args) + { + var player = TShock.Players[args.Who]; + + if (!player.IsLoggedIn) + { + player.IsDisabledForSSC = true; + player.SendErrorMessage(String.Format( + "Server side characters is enabled! Please {0}register or {0}login to play!", Commands.Specifier)); + player.LoginHarassed = true; + } + } + + private void OnLeave(LeaveEventArgs args) + { + var tsplr = TShock.Players[args.Who]; + if (tsplr == null) + { + return; + } + + if (tsplr.ReceivedInfo) + { + if (tsplr.IsLoggedIn && !tsplr.IsDisabledPendingTrashRemoval && (!tsplr.Dead || tsplr.TPlayer.difficulty != 2)) + { + tsplr.PlayerData.CopyCharacter(tsplr); + TShock.CharacterDB.InsertPlayerData(tsplr); + } + } + } } } diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 476995bb0..3a54895e9 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -1627,13 +1627,7 @@ private void OnGreetPlayer(GreetPlayerEventArgs args) if (!player.IsLoggedIn) { - if (Main.ServerSideCharacter) - { - player.IsDisabledForSSC = true; - player.SendErrorMessage(String.Format("Server side characters is enabled! Please {0}register or {0}login to play!", Commands.Specifier)); - player.LoginHarassed = true; - } - else if (Config.RequireLogin) + if (Main.ServerSideCharacter && Config.RequireLogin) { player.SendErrorMessage("Please {0}register or {0}login to play!", Commands.Specifier); player.LoginHarassed = true; From 749dfbbe3c251c327a67133a8f4fdaa9e626c0cf Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Mon, 29 Oct 2018 22:46:16 +0800 Subject: [PATCH 09/11] Initial plugin reference in constructor. --- TShockAPI/SSC.cs | 4 +++- TShockAPI/TShock.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs index 510c0688a..e76c48e32 100644 --- a/TShockAPI/SSC.cs +++ b/TShockAPI/SSC.cs @@ -40,8 +40,10 @@ internal sealed class SSC private TShock Plugin; /// A new SSC system. - internal SSC() + internal SSC(TShock plugin) { + Plugin = plugin; + // Setup GetDataHandlers GetDataHandlers.Connecting += Login; GetDataHandlers.PlayerSpawn += OnSpawn; diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 3a54895e9..a0ea1e866 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -331,7 +331,7 @@ public override void Initialize() Bouncer = new Bouncer(); RegionSystem = new RegionHandler(Regions); if(Main.ServerSideCharacter) - SSC = new SSC(); + SSC = new SSC(this); var geoippath = "GeoIP.dat"; if (Config.EnableGeoIP && File.Exists(geoippath)) From 25c84b5a99648082db1e35bf18978b879501e76c Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Fri, 16 Nov 2018 22:41:25 +0800 Subject: [PATCH 10/11] add data model --- TShockAPI/SSC.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs index e76c48e32..40bc69bb6 100644 --- a/TShockAPI/SSC.cs +++ b/TShockAPI/SSC.cs @@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License */ using System; using System.Collections.Generic; +using System.Data; using System.Linq; using Terraria.ID; using TShockAPI.DB; @@ -36,12 +37,15 @@ namespace TShockAPI /// The TShock server side character subsystem. internal sealed class SSC { + /// The database connection layer to for the ssc subsystem. + private CharacterManager DataModel; /// A reference to the TShock plugin so we can register events. private TShock Plugin; /// A new SSC system. - internal SSC(TShock plugin) + internal SSC(TShock plugin, IDbConnection database) { + DataModel = new CharacterManager(database); Plugin = plugin; // Setup GetDataHandlers @@ -110,7 +114,7 @@ internal void OnPlayerUpdate(object sender, PlayerUpdateEventArgs args) if (args.Player.Confused && args.Player.IsLoggedIn) { if (tplr.controlUp) - { + { tplr.controlDown = true; tplr.controlUp = false; } From f512dff471cf7bcac736ada2791533c9ee3c0b8d Mon Sep 17 00:00:00 2001 From: AxeelAnder Date: Fri, 16 Nov 2018 22:43:42 +0800 Subject: [PATCH 11/11] replace TShock.CharacterDB with DataModel --- TShockAPI/SSC.cs | 8 ++++---- TShockAPI/TShock.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/TShockAPI/SSC.cs b/TShockAPI/SSC.cs index 40bc69bb6..e55d57ed1 100644 --- a/TShockAPI/SSC.cs +++ b/TShockAPI/SSC.cs @@ -70,7 +70,7 @@ internal void Login(object sender, GetDataHandledEventArgs args) if (args.Player.HasPermission(Permissions.bypassssc)) { args.Player.PlayerData.CopyCharacter(args.Player); - TShock.CharacterDB.InsertPlayerData(args.Player); + DataModel.InsertPlayerData(args.Player); } args.Player.PlayerData.RestoreCharacter(args.Player); @@ -145,7 +145,7 @@ internal void OnKillMe(object sender, KillMeEventArgs args) { if (args.Player.TPlayer.difficulty == 2 && args.Player.IsLoggedIn) { - if (TShock.CharacterDB.RemovePlayer(args.Player.Account.ID)) + if (DataModel.RemovePlayer(args.Player.Account.ID)) { args.Player.SendErrorMessage( "You have fallen in hardcore mode, and your items have been lost forever."); @@ -165,7 +165,7 @@ internal void OnGameUpdate(EventArgs args) if (player != null && player.IsLoggedIn && !player.IsDisabledPendingTrashRemoval) { - TShock.CharacterDB.InsertPlayerData(player); + DataModel.InsertPlayerData(player); } } @@ -199,7 +199,7 @@ private void OnLeave(LeaveEventArgs args) if (tsplr.IsLoggedIn && !tsplr.IsDisabledPendingTrashRemoval && (!tsplr.Dead || tsplr.TPlayer.difficulty != 2)) { tsplr.PlayerData.CopyCharacter(tsplr); - TShock.CharacterDB.InsertPlayerData(tsplr); + DataModel.InsertPlayerData(tsplr); } } } diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index a0ea1e866..370ff49c6 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -331,7 +331,7 @@ public override void Initialize() Bouncer = new Bouncer(); RegionSystem = new RegionHandler(Regions); if(Main.ServerSideCharacter) - SSC = new SSC(this); + SSC = new SSC(this, DB); var geoippath = "GeoIP.dat"; if (Config.EnableGeoIP && File.Exists(geoippath))