aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/util/ISerializableObject.java
blob: 51bee67b91d3ab1d74a3e168dc61b38df62de496 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package gregtech.api.util;

import java.io.IOException;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTSizeTracker;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;

import com.google.common.io.ByteArrayDataInput;

import io.netty.buffer.ByteBuf;

/**
 * We could well have used {@link java.io.Serializable}, but that's too slow and should generally be avoided
 *
 * @author glease
 */
public interface ISerializableObject {

    @Nonnull
    ISerializableObject copy();

    /**
     * If you are overriding this, you must <b>NOT</b> return {@link NBTTagInt} here! That return type is how we tell
     * that we are loading legacy data, and only {@link LegacyCoverData} is allowed to return it. You probably want to
     * return {@link NBTTagCompound} anyway.
     */
    @Nonnull
    NBTBase saveDataToNBT();

    /**
     * Write data to given ByteBuf The data saved this way is intended to be stored for short amount of time over
     * network. DO NOT store it to disks.
     */
    // the NBT is an unfortunate piece of tech. everything uses it but its API is not as efficient as could be
    void writeToByteBuf(ByteBuf aBuf);

    void loadDataFromNBT(NBTBase aNBT);

    /**
     * Read data from given parameter and return this. The data read this way is intended to be stored for short amount
     * of time over network.
     * 
     * @param aPlayer the player who is sending this packet to server. null if it's client reading data.
     */
    // the NBT is an unfortunate piece of tech. everything uses it but its API is not as efficient as could be
    @Nonnull
    ISerializableObject readFromPacket(ByteArrayDataInput aBuf, @Nullable EntityPlayerMP aPlayer);

    /**
     * Reverse engineered and adapted {@link cpw.mods.fml.common.network.ByteBufUtils#readTag(ByteBuf)} Given buffer
     * must contain a serialized NBTTagCompound in minecraft encoding
     */
    static NBTTagCompound readCompoundTagFromGreggyByteBuf(ByteArrayDataInput aBuf) {
        short size = aBuf.readShort();
        if (size < 0) return null;
        else {
            byte[] buf = new byte[size]; // this is shit, how many copies have we been doing?
            aBuf.readFully(buf);
            try {
                return CompressedStreamTools.func_152457_a(buf, new NBTSizeTracker(2097152L));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * Reverse engineered and adapted {@link cpw.mods.fml.common.network.ByteBufUtils#readItemStack(ByteBuf)} Given
     * buffer must contain a serialized ItemStack in minecraft encoding
     */
    static ItemStack readItemStackFromGreggyByteBuf(ByteArrayDataInput aBuf) {
        ItemStack stack = null;
        short id = aBuf.readShort();
        if (id >= 0) {
            byte size = aBuf.readByte();
            short meta = aBuf.readShort();
            stack = new ItemStack(Item.getItemById(id), size, meta);
            stack.stackTagCompound = readCompoundTagFromGreggyByteBuf(aBuf);
        }
        return stack;
    }

    final class LegacyCoverData implements ISerializableObject {

        private int mData;

        public LegacyCoverData() {}

        public LegacyCoverData(int mData) {
            this.mData = mData;
        }

        @Override
        @Nonnull
        public ISerializableObject copy() {
            return new LegacyCoverData(mData);
        }

        @Override
        @Nonnull
        public NBTBase saveDataToNBT() {
            return new NBTTagInt(mData);
        }

        @Override
        public void writeToByteBuf(ByteBuf aBuf) {
            aBuf.writeInt(mData);
        }

        @Override
        public void loadDataFromNBT(NBTBase aNBT) {
            mData = aNBT instanceof NBTTagInt ? ((NBTTagInt) aNBT).func_150287_d() : 0;
        }

        @Override
        @Nonnull
        public ISerializableObject readFromPacket(ByteArrayDataInput aBuf, EntityPlayerMP aPlayer) {
            mData = aBuf.readInt();
            return this;
        }

        public int get() {
            return mData;
        }

        public void set(int mData) {
            this.mData = mData;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            LegacyCoverData that = (LegacyCoverData) o;

            return mData == that.mData;
        }

        @Override
        public int hashCode() {
            return mData;
        }

        @Override
        public String toString() {
            return String.valueOf(mData);
        }
    }
}