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
|
package tectech.mechanics.spark;
import static gregtech.api.enums.Mods.Thaumcraft;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import eu.usrv.yamcore.network.client.AbstractClientMessageHandler;
import io.netty.buffer.ByteBuf;
import thaumcraft.client.fx.bolt.FXLightningBolt;
// TODO Re-work how sparks are distributed
public class RendererMessage implements IMessage {
HashSet<ThaumSpark> sparkList;
public RendererMessage() {}
@SuppressWarnings("unchecked")
@Override
public void fromBytes(ByteBuf pBuffer) {
if (FMLCommonHandler.instance()
.getSide()
.isServer()) return;
try {
// I'd love to know why I need to offset by one byte for this to work
byte[] boop = pBuffer.array();
boop = Arrays.copyOfRange(boop, 1, boop.length);
InputStream is = new ByteArrayInputStream(boop);
ObjectInputStream ois = new ValidatingObjectInputStream(is);
Object data = ois.readObject();
sparkList = (HashSet<ThaumSpark>) data;
} catch (IOException | ClassNotFoundException ignored) {}
}
@Override
public void toBytes(ByteBuf pBuffer) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(sparkList);
oos.flush();
InputStream is = new ByteArrayInputStream(baos.toByteArray());
pBuffer.writeBytes(is, baos.toByteArray().length);
} catch (IOException ignore) {}
}
public static class RendererData extends RendererMessage {
public RendererData() {}
public RendererData(HashSet<ThaumSpark> eSparkList) {
sparkList = eSparkList;
}
}
public static class ClientHandler extends AbstractClientMessageHandler<RendererData> {
@Override
public IMessage handleClientMessage(EntityPlayer pPlayer, RendererData pMessage, MessageContext pCtx) {
// disgusting
Random localRand = Minecraft.getMinecraft().theWorld.rand;
int[] zapsToUse = new int[4];
for (int i = 0; i < 3; i++) {
zapsToUse[i] = localRand.nextInt(pMessage.sparkList.size());
}
int i = 0;
for (ThaumSpark sp : pMessage.sparkList) {
for (int j : zapsToUse) {
if (i == j) {
thaumLightning(sp.x, sp.y, sp.z, sp.xR, sp.yR, sp.zR, sp.wID);
}
}
i++;
}
pMessage.sparkList.clear();
return null;
}
}
@SideOnly(Side.CLIENT)
private static void thaumLightning(int tX, int tY, int tZ, int tXN, int tYN, int tZN, int wID) {
// This is enough to check for thaum, since it only ever matters for client side effects (Tested not to crash)
if (Thaumcraft.isModLoaded()) {
World world = Minecraft.getMinecraft().theWorld;
if (world.provider.dimensionId == wID) {
FXLightningBolt bolt = new FXLightningBolt(
world,
tX + 0.5F,
tY + 0.5F,
tZ + 0.5F,
tX + tXN + 0.5F,
tY + tYN + 0.5F,
tZ + tZN + 0.5F,
world.rand.nextLong(),
6,
0.5F,
8);
bolt.defaultFractal();
bolt.setType(2);
bolt.setWidth(0.125F);
bolt.finalizeBolt();
}
}
}
private static class ValidatingObjectInputStream extends ObjectInputStream {
private static final Logger logger = LogManager.getLogger();
private static final Marker securityMarker = MarkerManager.getMarker("SuspiciousPackets");
private ValidatingObjectInputStream(InputStream in) throws IOException {
super(in);
}
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
String name = desc.getName();
if (!name.equals("java.util.HashSet") && !name.equals("tectech.mechanics.spark.ThaumSpark")) {
logger.warn(securityMarker, "Received packet containing disallowed class: " + name);
throw new RuntimeException();
}
return super.resolveClass(desc);
}
}
}
|