Casimir255 / QuantumHangar-EOL-

This is a server hangar and grid market plugin
Apache License 2.0
9 stars 21 forks source link

Can not Auto Dupe/Loss protection between server crashes #73

Open SWQXDBA opened 1 year ago

SWQXDBA commented 1 year ago

In plugin page https://torchapi.com/plugins/view/24fc7724-0740-4a54-8bb3-1191fd3c8db4 I see that

plugin can Auto Dupe/Loss protection between server crashes.

And then I make a test.

First, I paste a Grid for test.
Second, I run command "!save" to save game.
Third I use "!h save" to save the grid into hanger. Fourth ,I make the server crash with a command I write.

        [Command("stackOverFlow", "test")]
        [Permission(MyPromoteLevel.Admin)]
        public void stackOverFlow()
        {
            stackOverFlow();
        }

and then I kill the server. This option is mock when a error happen and server can't autosave.

Fifth, I restart the server,and then I had copy a Grid(the one in the hanger,other one in game).


By test seems that Hangar can't promise prevent Clone and Loss of grid.

In the multiplayer online environment with many mods, server crashes are frequent. Players can clone spaceships through this way, or players will lose spaceships.

kontu commented 1 year ago

Old information; dupe protection is not in the plugin. Didn't pan out. it was in for awhile under trial but just didn't pan out

SWQXDBA commented 1 year ago

I have a well-run implementation that can recover automatically and avoid most problems. My server has a plugin written by myself, which provides functions similar to QuantumHangar. Among them, the functions of ship synchronization and crash recovery between multiple servers are realized. Their approximate implementation is as follows: Add two new subfolders to each player's hangar folder: loadTemp and saveTemp. When the player loads a grid from the hangar, he cuts the grid file into loadTemp and loads the grid in the game. When the player saves a grid from the game, the serialized grid file will go into saveTemp instead of directly into the hangar folder. This means that players can load grids from the saveTemp folder and the hangar folder.

I call the two key steps hangar synchronization operation and hangar recovery operation.

Hangar synchronization operation: When the game is saved, delete the files in loadTemp and cut the files in saveTemp into the hangar folder. Hangar recovery operation: every time the server is started, the files in loadTemp are cut into the hanger folder, and the files in saveTemp are deleted.

In order to avoid the problem of copying the grid in a multi-server environment, each server should have its own saveTemp and loadTemp folders. When the player runs in a server:! H list, he can only see the grid in the saveTemp of his server and the grid in the hangar. I call the grids in saveTemp "unsynchronized grids", and they can't be loaded in other servers for the time being.

Because the synchronization is carried out when the game is saved, the more frequently the game is saved, the more timely the synchronization between servers is. My setting is to automatically save the game once every 15 minutes. This will not bring many bad experiences, because players only need to play in one server in most cases.

However, in order to ensure non-invasion and higher success rate, it is necessary to ensure that the synchronization operation of the hangar should be carried out every time the server is saved, and when the game is saved, the synchronization operation of the hangar cannot be carried out.

In order to realize it, it needs to be repaired by patch. After many failed experiments, the method of "MySessionSnapshot.Save" has the best repair effect. some of the code may like this:

    internal static readonly MethodInfo Save =
        typeof(MySessionSnapshot).GetMethod(nameof(MySessionSnapshot.Save),
            BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) ??
        throw new Exception("Failed to find patch method");

 public static void SaveSuffixes(ref bool __result)
    {
        if (__result)
        {
           DoHangerSync();
        }

    }

After my test, there is still a low probability that this scheme can't solve the problem (such as an error during synchronization). But it works well in most cases. In the early stage of writing my own plug-in, I referred to many codes of quantum hangars. Originally, I wanted to submit a pull request. But I found that some stateful saving files were used in the quantum hangar. (The quantum hangar saves some meta-information through a PlayerInfo.json file. If I want to manually modify the player's hangar, it will be very inconvenient. In fact, this is why I chose to implement a stateless library plug-in myself) Moreover, because Quantum hangar provides some third-party interfaces for other plug-ins, such as "NexusApi". I'm not familiar with it, and I'm afraid it will destroy its function. So I'm sorry I can't submit a PR. I'm just here to offer a suggestion on how to realize it.

Casimir255 commented 1 year ago

This is exactly what was in Hangar, but was removed for the simple fact that there is no way for you to know what happened to the grid ingame after unloading reliably. Did it separate? Did it transfer to a different server? Did players grind everything down? Did someone else grab it and hangar it?

It was decided that its safer not to do anything as anything similar to what you described and what I had would leave holes for players to abuse and dupe grids in any server environment. In nexus, or not. (many servers share their hangars). Sure, decreasing the save interval is better, its not something that should be considered or required when running the plugin.

There are fixes, but none are easy and would require a lot of effort to implement effectively. However, if you feel like your solution works, great! Just be aware that there are possibilities where duplication can occur.

I should go ahead and remove that line from the description.