TShock icon indicating copy to clipboard operation
TShock copied to clipboard

Provide a way for plugins to override TShock SSC

Open ZakFahey opened this issue 1 year ago • 5 comments

Add TShock.UseSSCInventory, which can be set to false by another plugin on initialization to override TShock's SSC implementation while keeping SSC on. This fixes the use case where you want to be able to override players' inventories from the server, but you don't want to use TShock's SSC system or force players to stay logged in.

Context: this functionality is in the internal Penguin Games server fork of TShock that we have, but I'm trying to merge everything from there upstream because I don't want to have to deal with maintaining a fork. Especially with 1.4.5 coming out any day now, I don't want to create more work for myself. We use SSC but allow logged-out users to play, and I'm sure that that's the case for other public servers as well.

Not all instances of Main.ServerSideCharacter were replaced because this is the code our server uses, and it works. I could understand wanting to change most if not all instances of it, though.

ZakFahey avatar Feb 18 '24 19:02 ZakFahey

That config value combines two things: enabling SSC mode for Terraria clients, which lets you directly set their inventory, and TShock's SSC system, which saves players' inventories to TShock's database and disables logged out characters. I want one but not the other.

I'd acknowledge that this PR may be redundant if it's trivial to just have the config flag be off but override Terraria's SSC checks in my own plugin.

ZakFahey avatar Feb 22 '24 03:02 ZakFahey

There are three fields related: Main.ServerSideCharacter, the newly introduced TShock.UsingTShockSSC, and the (almost) unused SscSettings.Enabled. I guess he is proposing moving the function of the new TShock.UsingTShockSSC to replace the unused SscSettings.Enabled (since the latter is only used once for Main.ServerSideCharacter = SscSettings.Enabled)?

sgkoishi avatar Feb 22 '24 04:02 sgkoishi

Yeah, that's what I did on my fork https://github.com/Arthri/TShock/commit/a1fce06b7a4007ebe5afd37b03230e98332b27f9. I replaced the parts relevant to TShock's SSC and left the others untouched(like /rocket)

Arthri avatar Feb 22 '24 09:02 Arthri

Hmm, I'm noticing that if I turn off TShock's SSC just in the config on a normal version of it, while Main.ServerSideCharacter is false, players can still have their inventory slots set directly. Looking at the code, it does seem like it being false affects some things, but I can't immediately see them when joining a server.

ZakFahey avatar Mar 01 '24 18:03 ZakFahey

I am going to close this PR because I have found a workaround. You just need to

  • Disable SSC in the config
  • Spoof Main.ServerSideCharacter as true in packets sent to clients.
  • GiveItem does not give items directly anymore due to this line
private void GiveItemDirectly(int type, int stack, int prefix)
{
    if (ItemID.Sets.IsAPickup[type] || !Main.ServerSideCharacter || this.IsDisabledForSSC)
    {
        GiveItemByDrop(type, stack, prefix);
        return;
    }

so as a workaround to that problem I have added this command hook

TShockAPI.Hooks.PlayerHooks.PlayerCommand += OnCommand;
...
private void OnCommand(PlayerCommandEventArgs args)
{
    switch (args.CommandName)
    {
        case "item":
        case "i":
        case "give":
        case "g":
            // If Main.ServerSideCharacter is true, we're in the override for this and shouldn't
            // run anything. Otherwise we'd go in an infinite loop.
            if (!Main.ServerSideCharacter)
                break;
            Main.ServerSideCharacter = true;
            try
            {
                TShockAPI.Commands.HandleCommand(args.Player, $"/{args.CommandText}");
            }
            finally
            {
                Main.ServerSideCharacter = false;
            }
            args.Handled = true;
            break;
    }
}

which will make Main.ServerSideCharacter be true when I need it. Then any instance of GiveItem in my own plugin needs to be replaced with a util that does something similar.

ZakFahey avatar Jul 21 '24 17:07 ZakFahey