Solved BungeeCord Network - Best way to manage data

Discussion in 'Spigot Plugin Development' started by SmokingIsBadMkay, May 5, 2017.

  1. You probably can (serialize your object and store it in binary format), but I would not recommend it.
     
  2. Because he doesn't understand how Redis works.
    You have to serialize and deserialize, which there really is nothing against at all.
    Store it as binary, HEX, plain string, whatever you'd like.
    As long as it's persistent and also has backwards compatibility it'll work great.
     
    • Friendly Friendly x 1
    • Useful Useful x 1
  3. Did some research, would this work? :)


    Code (Text):
        public void test() {
            //Class instance example
            Nick nick = new Nick();
         
            //Convert to gson string
            Gson gson = new Gson();
            String json = gson.toJson(nick);
         
            //Convert gson string to Nick object
            Gson gson2 = new Gson();
            Nick new_nick = gson2.fromJson("this is where the gson string variable would be", Nick.class);
        }
     
  4. no
    you'll need a custom deserializer, like i said.
    this is how coalescebot's Punishment is like, at least (kotlin):
    Code (Java):
    class PunishmentSerializer : JsonDeserializer<Punishment>, JsonSerializer<Punishment> {
    override fun serialize(src: Punishment, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
    val obj = JsonObject()
    obj.add("reason", JsonPrimitive(src.reason.name.toUpperCase()))
    obj.add("punished", JsonPrimitive(src.punished.id))
    obj.add("punishee", JsonPrimitive(src.punishee.id))
    obj.add("description", if (src.description == null) JsonNull.INSTANCE else JsonPrimitive(src.description))
    obj.add("expiration", if (src.expiration == null) JsonNull.INSTANCE else JsonPrimitive(src.expiration))
    return obj
    }

    override fun deserialize(json: JsonElement, typeOfT: Type?, context: JsonDeserializationContext?): Punishment? {
    val obj = json.asJsonObject
    val reason = Reason.valueOf(obj.get("reason").asString.toUpperCase())
    val punished = Bot.instance.jda.getUserById(obj.get("punished").asString)
    val punishee = Bot.instance.jda.getUserById(obj.get("punishee").asString)
    val description = obj.get("reason")?.asString // String?
    val expiration = obj.get("expiration")?.asLong
    return Punishment(reason, punished, punishee, description, expiration)
    }
    }
    and naturally spigot fucks the indents.
     
  5. Decided to test that code, this is what I did:
    Code (Text):
        public void test() {
            //Class instance example
            Nick nick = new Nick();
            nick.set("Test");
         
            //Convert to gson string
            Gson gson = new Gson();
            String json = gson.toJson(nick);
            System.err.println(json);
         
            //Convert gson string to Nick object
            Gson gson2 = new Gson();
            Nick new_nick = gson2.fromJson(json, Nick.class);
            System.err.println(new_nick.get());
        }
    Nick class:
    Code (Text):
    package test;

    public class Nick
    {

        String s = "";
     
        public void set(String s) {
            this.s = s;
        }
     
        public String get() {
            return this.s;
        }
     
    }
     
    This is the result:
    [​IMG]

    Seems to work. :rolleyes:
     
  6. At least make sure to add serializers for Bukkit classes which have a lot of info, e.g. Location and World.
     
  7. Going to play around with both my code and what you suggested, will use what works best and is the easiest to use.

    Anyways, thanks a lot!


    I'm going mark this thread as solved now.
    Thanks to everyone who suggested their idea's!
     
  8. with gson, if you have any of your 'own' objects within the class, you're going to need a serializer, which has been mentioned before. otherwise, if you're using normal primitives etc, (String, int, etc) then you'll be fine.

    example when usage of a custom serializer/deserializer:

    Code (Java):

    public class CustomPlayer {
     
          private String name;
          private UUID uuid;
          private Rank rank; //assume this is an eum. enum objects are handled by gson, no need for a serializer/deserializer
          private Clan clan; //you would have to make a custom serializer for this, since gson does not know how or what to serialize the object/its contents

         public CustomPlayer() {
         }


    public class Clan {

          private Set<UUID> members;
          private String name;

         public Clan() {

         }

    }
     
  9. instances of both classes can be (de)serialized without a custom type adapter.

    https://hastebin.com/iyuhalomay.cs
     
    #31 NyxCode, May 6, 2017
    Last edited: May 6, 2017
  10. perhaps im missing something? last time i tried this, i was thrown an error until i registered an adapter with an object in the chosen class.
     
  11. electronicboy

    IRC Staff

    Gson will attempt to serialise and deserialize everything naturally by attempting to resolve the classes and the information inside of them, for simple objects, a custom adaptor is not needed; Only in cases where your objects are a bit more complicated than normal, or you're expecting stuff to be handled in a certain way, e.g. you wouldn't want Gson to try to serialize a Location object, because a Location object has a CraftWorld object, which has a NMS world object, and before you know it, it's trying to serialize a whole world into json ;P
     
    • Agree Agree x 1
    • Useful Useful x 1
  12. Would it also be possible/recommended to save the serialised strings to mysql? So I would basicly save my whole PlayerData class in one table.
     
  13. Trust me, it works ( :
    please dont. MySQL is a relational database - so you should split your data in different tables. For example:
    Table "UserIDs": id: Int | uuid: Char(36)
    Table "UserNames": id: Int | name: Varchar
    Table "UserPermissions": id: Int | perm: Varchar
    Edit: When you store serialized data in Redis, I would not recommend json. ((de)serializing is pretty slow, serialized data is big). Just use Javas serialization (easy) or Googles Protocolbuffer.
     
    #35 NyxCode, May 7, 2017
    Last edited: May 7, 2017
  14. Serializator

    Supporter

    What's wrong with that? Redis is lightning fast so the player should get a 40 tickrate now, right?
    It's simply math, obviously!

    (minecraft tickrate * redis lightning speed * air friction) / momentum of gravity = obvious tickrate
     
    • Funny Funny x 4