JohnathonNow / Bending

A 2D, multiplayer online action game.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Re-write networking stuff

JohnathonNow opened this issue · comments

final int read = input.read();
// System.out.println(read);
// System.out.println("MR: "+Server.MESSAGEIDs[read]);
pc++;
switch (read) {
case Server.ID:
ID = Server.readByteBuffer(input).getInt();
world.ID = ID;
break;
case Server.MESSAGE:
final ByteBuffer gotten = Server.readByteBuffer(input);
final int color = gotten.getInt();
final String message = Server.getString(gotten);
addChat(message, new Color(color));
break;
case Server.LOGIN:
int iid;
final ByteBuffer rasputin = Server.readByteBuffer(input);
iid = rasputin.getInt();
// iid = input.read();
final String feliceNavidad = Server.getString(rasputin);
final Player yes = new Player(300, 300,
new byte[] { rasputin.get(), rasputin.get(), rasputin.get(), rasputin.get(),
rasputin.get(), rasputin.get() },
new int[] { rasputin.getInt(), rasputin.getInt(), rasputin.getInt(),
rasputin.getInt(), rasputin.getInt(), rasputin.getInt() },
new int[] { rasputin.getInt(), rasputin.getInt(), rasputin.getInt(),
rasputin.getInt(), rasputin.getInt(), rasputin.getInt() });
world.playerList.add(yes);
final boolean sameTeam = rasputin.get() == 12;
// yes.username = Server.getString(rasputin);
// system.out.println("Player joined with ID:"+iid);
if (sameTeam) {
myTeam.add(iid);
} else {
badTeam.add(iid);
}
yes.myTeam = sameTeam;
yes.ID = iid;
yes.username = feliceNavidad;
addChat(yes.username + " has joined the game.", Color.RED);
loggedIn = true;
break;
case Server.MOVE:
ByteBuffer reading = Server.readByteBuffer(input);
final int idtomove = reading.getShort();
// system.out.println("ID: "+idtomove);
if (idtomove == ID) {
world.x = reading.getShort();
world.y = reading.getShort();
world.move = reading.getShort();
world.vspeed = reading.getShort();
world.leftArmAngle = reading.getShort();
world.rightArmAngle = reading.getShort();
world.status = reading.getShort();
}
for (final Player r : world.playerList) {
if (r.ID == idtomove) {
// system.out.println("hi");
r.x = reading.getShort();
r.y = reading.getShort();
r.move = reading.getShort();
r.vspeed = reading.getShort();
r.leftArmAngle = reading.getShort();
r.rightArmAngle = reading.getShort();
r.status = reading.getShort();
break;
}
}
break;
case Server.MAP:
int x;
reading = Server.readByteBuffer(input);
x = reading.getInt();
// y = input.readInt();
// System.out.println("SDFSDF"+x);
for (int i = x; i < x + 100; i++) {
reading.get(world.ground.cellData[i]);
}
// System.out.println("yay");
sendRequest = true;
break;
case Server.AI:
final ByteBuffer reader = Server.readByteBuffer(input);
// putInt(e.X).putInt(e.Y).putInt(e.HP).putInt(e.move).putInt(e.yspeed).putInt(e.target).putInt(e.id);
final int redX = reader.getInt();
final int redY = reader.getInt();
final int redmove = reader.getInt();
final int redyspeed = reader.getInt();
final int redHP = reader.getInt();
final int redid = reader.getInt();
final int tar = reader.getInt();
for (final Entity p : world.entityList) {
if (!(p instanceof EnemyEntity))
continue;
final EnemyEntity e = (EnemyEntity) p;
if (e.MYID == redid) {
e.X = redX;
e.Y = redY;
e.HP = redHP;
e.move = redmove;
e.yspeed = redyspeed;
e.target = tar;
}
}
break;
case Server.ENTIREWORLD:
// system.out.println("WOAH");
readWorld();
// system.out.println("SCORE!");
busy = false;
break;
case Server.DIG:
ByteBuffer toRead = Server.readByteBuffer(input);
int ix, iy, ir;
ix = toRead.getInt();
iy = toRead.getInt();
ir = toRead.getInt();
world.ground.ClearCircle(ix, iy, ir);
// system.out.println("DIG!");
break;
case Server.FILL:
toRead = Server.readByteBuffer(input);
ix = toRead.getInt();
iy = toRead.getInt();
ir = toRead.getInt();
final byte etg = toRead.get();
world.ground.FillCircleW(ix, iy, ir, etg);
// system.out.println("FILL!");
break;
case Server.CHARGE:
toRead = Server.readByteBuffer(input);
ix = toRead.getInt();
iy = toRead.getInt();
ir = toRead.getInt();
final int energy = toRead.getInt();
final int maker = toRead.getInt();
if (Client.pointDis(world.x, world.y, ix, iy) < ir) {
energico += energy;
if (maker != ID && (gameMode > 0 ? !myTeam.contains(maker) : true)) {
if (maker != 0) {
lastHit = maker;
}
hurt(12);
killMessage = "~ was electrified by `.";
if (world.inBounds(world.x, world.y)
&& world.ground.cellData[(int) world.x][(int) world.y] == Constants.WATER) {
hurt(12);
killMessage = "~ will never go in the water during a storm again, thanks to `!";
}
}
}
world.entityList.add(new ShockEffectEntity(ix, iy, ir));
// system.out.println("FILL!");
break;
case Server.HURT:
toRead = Server.readByteBuffer(input);
HP -= toRead.getInt();
// system.out.println("FILL!");
break;
case Server.WORLDEXPAND:
// system.out.println("IT's getting bigger!");
busy = true;
toRead = Server.readByteBuffer(input);
final int newx = toRead.getInt();
final int si = toRead.getInt();
final byte dir = toRead.get();
world.wIdTh += si;
final byte list[][] = new byte[world.wIdTh][world.hEigHt];
for (int i = 0; i < world.ground.w; i++) {
System.arraycopy(world.ground.cellData[i], 0, list[i], 0, world.ground.h);
}
world.ground.cellData = list;
world.ground.w = world.wIdTh;
if (dir == 1) {
for (int i = newx; i < world.wIdTh; i++) {
toRead.get(world.ground.cellData[i]);
}
}
if (dir == 2) {
for (int i = newx; i < si; i++) {
toRead.get(world.ground.cellData[i]);
}
world.x += si;
}
readEntityList(toRead);
busy = false;
break;
case Server.SPELL:
ByteBuffer buf;
buf = Server.readByteBuffer(input);
int subID = buf.getInt();
int px = buf.getInt();
int py = buf.getInt();
int mx = buf.getInt();
int my = buf.getInt();
int pid = buf.getInt();
int eid = buf.getInt();
Spell.getSpell(subID).getActionNetwork(world, px, py, mx, my, pid, eid, buf);
break;
case Server.FREEZE:
// ByteBuffer buf;
buf = Server.readByteBuffer(input);
int fX = buf.getInt();
int fY = buf.getInt();
int fR = buf.getInt();
world.ground.freeze(fX, fY, fR);
break;
case Server.SANDINATE:
// ByteBuffer buf;
buf = Server.readByteBuffer(input);
fX = buf.getInt();
fY = buf.getInt();
fR = buf.getInt();
world.ground.sandinate(fX, fY, fR);
break;
case Server.PUDDLE:
// ByteBuffer buf;
buf = Server.readByteBuffer(input);
fX = buf.getInt();
fY = buf.getInt();
fR = buf.getInt();
world.ground.puddle(fX, fY, fR);
break;
case Server.DESTROY:
// ByteBuffer buf;
buf = Server.readByteBuffer(input);
int idtokill = buf.getInt();
for (int i = 0; i < world.entityList.size(); i++) {
if (world.entityList.get(i).MYID == idtokill) {
world.entityList.remove(i);
continue;
}
}
break;
case Server.DRAIN:
buf = Server.readByteBuffer(input);
final int hpt = buf.getInt();
HP += hpt;
break;
case Server.STEAM:
// ByteBuffer buf;
buf = Server.readByteBuffer(input);
final int xxxx = buf.getInt(), yyyy = buf.getInt();
idtokill = buf.getInt();
for (int i = 0; i < world.entityList.size(); i++) {
if (world.entityList.get(i).MYID == idtokill) {
world.entityList.remove(i);
continue;
}
}
world.entityList.add(new SteamEntity(xxxx, yyyy));
break;
case Server.DEATH:
// ByteBuffer buf;
buf = Server.readByteBuffer(input);
fX = buf.getInt();
final int fX2 = buf.getInt();
if (fX2 != fX) {
if (fX == ID) {
XP += 25;
gameService.earnExperience(XP, username);
score++;
if (killingSpree == 0) {
killingSpree = Math.E;
} else {
killingSpree *= Math.E;
}
}
for (final Player p : world.playerList) {
if (p.ID == fX) {
p.score++;
}
}
}
break;
case Server.SCORE:
// ByteBuffer buf;
buf = Server.readByteBuffer(input);
final int idd = buf.getInt();
final int scored = buf.getInt();
if (idd == ID) {
XP += 10;
gameService.earnExperience(XP, username);
score = scored;
if (killingSpree == 0) {
killingSpree = Math.E;
} else {
killingSpree *= Math.E;
}
}
for (final Player p : world.playerList) {
if (p.ID == idd) {
p.score = scored;
}
}
break;
case Server.LEAVE:
// ByteBuffer buf;
buf = Server.readByteBuffer(input);
fX = buf.getInt();
for (final Player p : world.playerList) {
if (p.ID == fX) {
if (myTeam.contains(p.ID)) {
myTeam.remove(myTeam.indexOf(p.ID));
} else {
badTeam.remove(badTeam.indexOf(p.ID));
}
addChat(p.username + " has left the game.", Color.RED);
world.playerList.remove(p);
break;
}
}
break;

case Server.LOGIN:
ByteBuffer bb = Server.readByteBuffer(in);
long auth = bb.getLong();
if (auth != Client.getAuth()) {
killMe();// HACKER!
}
this.username = Server.getString(bb);
out.addMesssage(ByteBuffer.allocate(4).putInt(ID), Server.ID);
// handle.newPlayer(ID, username);
writeWorld();
byte[] clothing = new byte[] { bb.get(), bb.get(), bb.get(), bb.get(), bb.get(), bb.get() };
cloth = clothing;
int[] colors = new int[] { bb.getInt(), bb.getInt(), bb.getInt(), bb.getInt(), bb.getInt(),
bb.getInt() };
int[] colors2 = new int[] { bb.getInt(), bb.getInt(), bb.getInt(), bb.getInt(), bb.getInt(),
bb.getInt() };
colord = colors;
colord2 = colors2;
UDPPORT = bb.getInt();
System.err.println(username + " joined with ID " + ID + ", on UDPPORT " + UDPPORT + ".");
String gm = "";
switch (Server.gameMode) {
case Server.TEAMDEATHMATCH:
gm = "Team Death Match";
break;
case Server.FREEFORALL:
gm = "Free for All";
break;
case Server.KINGOFTHEHILL:
gm = "King of the Hill";
break;
case Server.THEHIDDEN:
gm = "The Hidden";
break;
case Server.SURVIVAL:
gm = "Survival";
break;
case Server.DEFENDER:
gm = "Defender";
break;
}
gm = "The next game type will be " + gm + ".";
out.addMesssage(Server.putString(ByteBuffer.allocate(gm.length() * 4 + 4).putInt(0x00FF3C), gm),
Server.MESSAGE);
if (Server.gameMode == Server.DEFENDER) {
gm = "You will be a" + (handle.team1.contains(ID) ? " defender." : "n attacker.");
out.addMesssage(Server.putString(ByteBuffer.allocate(gm.length() * 4 + 4).putInt(0x00FF3C), gm),
Server.MESSAGE);
}
for (PlayerOnline p : handle.playerList) {
if (p.ID != ID) {
byte sameTeam = (byte) ((handle.team1.contains(ID) && handle.team1.contains(p.ID))
|| (handle.team2.contains(ID) && handle.team2.contains(p.ID)) ? 12 : 0);
out.addMesssage(Server
.putString(ByteBuffer.allocate(75 + 4 + 4 + 4 * p.username.length()).putInt(p.ID),
p.username)
.put(p.cloth).putInt(p.colord[0]).putInt(p.colord[1]).putInt(p.colord[2])
.putInt(p.colord[3]).putInt(p.colord[4]).putInt(p.colord[5]).putInt(p.colord2[0])
.putInt(p.colord2[1]).putInt(p.colord2[2]).putInt(p.colord2[3]).putInt(p.colord2[4])
.putInt(p.colord2[5]).put(sameTeam), Server.LOGIN);
p.out.addMesssage(Server
.putString(ByteBuffer.allocate(75 + 4 + 4 + 4 * username.length()).putInt(ID), username)
.put(clothing).putInt(colors[0]).putInt(colors[1]).putInt(colors[2]).putInt(colors[3])
.putInt(colors[4]).putInt(colors[5]).putInt(colors2[0]).putInt(colors2[1])
.putInt(colors2[2]).putInt(colors2[3]).putInt(colors2[4]).putInt(colors2[5])
.put(sameTeam), Server.LOGIN);
}
}
loggedIn = true;
break;
case Server.LOGOUT:
killMe();
break;
case Server.MOVE:
ByteBuffer toRead = Server.readByteBuffer(in);
x = toRead.getShort();
y = toRead.getShort();
move = toRead.getShort();
vspeed = toRead.getShort();
leftArmAngle = toRead.getShort();
rightArmAngle = toRead.getShort();
status = toRead.getShort();
HP = toRead.getShort();
// System.out.print(ID+":");
handle.movePlayer(ID, x, y, move, vspeed, (int) leftArmAngle, (int) rightArmAngle, status, HP);
break;
case Server.DIG:
toRead = Server.readByteBuffer(in);
int ix, iy, ir;
ix = toRead.getInt();
iy = toRead.getInt();
ir = toRead.getInt();
handle.earth.ground.ClearCircle(ix, iy, ir);
toRead.rewind();
// System.out.println("DIG!");
ByteBuffer toSend = ByteBuffer.allocate(12);
handle.sendMessage(Server.DIG, toSend.putInt(ix).putInt(iy).putInt(ir));
break;
case Server.FILL:
toRead = Server.readByteBuffer(in);
ix = toRead.getInt();
iy = toRead.getInt();
ir = toRead.getInt();
byte etg = toRead.get();
handle.earth.ground.FillCircleW(ix, iy, ir, etg);
toRead.rewind();
// System.out.println("FILL!");
toSend = ByteBuffer.allocate(12);
handle.sendMessage(Server.FILL, toSend.putInt(ix).putInt(iy).putInt(ir));
break;
case Server.MAP:
// System.out.println("MAP REQUEST!");
// out.write(Server.MAP);
ByteBuffer buf;
buf = Server.readByteBuffer(in);
buf.getInt();
int viewX;
viewX = Math.min(Math.max(x - 50, 0), handle.earth.wIdTh - 100);
// viewY = Math.min(Math.max(p.y-150,0),earth.hEigHt-300);
toSend = ByteBuffer.allocate(300000);
toSend.putInt(viewX);
// p.out.writeInt(viewY);
for (int i = viewX; i < viewX + 100; i++) {
toSend.put(handle.earth.ground.cellData[i]);
}
handle.sendMessage(Server.MAP, toSend);
// System.out.println("SENt");
// Server.writeByteBuffer(toSend, out);
break;
case Server.MESSAGE:
// System.out.println("MESSAGE RECIEVED!");
buf = Server.readByteBuffer(in);
int color = buf.getInt();
String yes = Server.getString(buf);
if (yes.contains("/nextmap")) {
if (!voted) {
handle.nextVote++;
yes = (handle.nextVote + ((handle.nextVote > 1 ? " players are " : " player is ")
+ "voting for ending the match."));
voted = true;
}
}
handle.sendMessage(Server.MESSAGE,
Server.putString(ByteBuffer.allocate(yes.length() * 4 + 4).putInt(color), yes));
// System.out.println(new String(buff).trim());
break;
case Server.SPELL:
buf = Server.readByteBuffer(in);
int subID = buf.getInt();
int Xx = buf.getInt();
int Yy = buf.getInt();
int mX = buf.getInt();
int mY = buf.getInt();
int Iw = Server.getID();
if (Spell.getSpell(subID) instanceof EarthbendingSand) {
//TODO this code is duplicated and should not be
int number = handle.earth.ground.sandinate(Xx, Yy, 96);
number /= (32);
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX, mY, ID).setID(Iw));
if (number > 3) {
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, 30),
mY + (int) Client.lengthdir_y(4, 30), ID).setID(Iw + 1));
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, -30),
mY + (int) Client.lengthdir_y(4, -30), ID).setID(Iw + 2));
Server.MYID += 2;
}
if (number > 5) {
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, 45),
mY + (int) Client.lengthdir_y(4, 45), ID).setID(Iw + 3));
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, -45),
mY + (int) Client.lengthdir_y(4, -45), ID).setID(Iw + 4));
Server.MYID += 2;
}
if (number > 7) {
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, 60),
mY + (int) Client.lengthdir_y(4, 60), ID).setID(Iw + 5));
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, -60),
mY + (int) Client.lengthdir_y(4, -60), ID).setID(Iw + 6));
Server.MYID += 2;
}
if (number > 12) {
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, 15),
mY + (int) Client.lengthdir_y(4, 15), ID).setID(Iw + 7));
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, -15),
mY + (int) Client.lengthdir_y(4, -15), ID).setID(Iw + 8));
Server.MYID += 2;
}
if (number > 16) {
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, 35),
mY + (int) Client.lengthdir_y(4, 35), ID).setID(Iw + 9));
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, -35),
mY + (int) Client.lengthdir_y(4, -35), ID).setID(Iw + 10));
Server.MYID += 2;
}
if (number > 20) {
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, 45),
mY + (int) Client.lengthdir_y(4, 45), ID).setID(Iw + 11));
handle.earth.entityList.add(new SandEntity(Xx, Yy, mX + (int) Client.lengthdir_x(4, -45),
mY + (int) Client.lengthdir_y(4, -45), ID).setID(Iw + 12));
Server.MYID += 2;
}
handle.sendMessage(Server.SPELL, ByteBuffer.allocate(32).putInt(subID).putInt(Xx).putInt(Yy)
.putInt(mX).putInt(mY).putInt(ID).putInt(Iw).putInt(number));
Server.MYID += 2;
} else {
Spell.getSpell(subID).getActionNetwork(handle.earth, Xx, Yy, mX, mY, ID, Iw, buf);
handle.sendMessage(Server.SPELL, ByteBuffer.allocate(28).putInt(subID).putInt(Xx).putInt(Yy)
.putInt(mX).putInt(mY).putInt(ID).putInt(Iw));
}
break;
case Server.DEATH:
buf = Server.readByteBuffer(in);
subID = buf.getInt();
if (subID != ID) {
// handle.score[subID]++;
for (PlayerOnline p : handle.playerList) {
if (p.ID == subID) {
p.score++;
}
}
}
handle.sendMessage(Server.DEATH, ByteBuffer.allocate(9).putInt(subID).putInt(ID));
break;
case Server.DRAIN:
buf = Server.readByteBuffer(in);
subID = buf.getInt();
int hpt = buf.getInt();
if (subID != ID) {
// handle.score[subID]++;
for (PlayerOnline p : handle.playerList) {
if (p.ID == subID) {
p.out.addMesssage(ByteBuffer.allocate(4).putInt(hpt), Server.DRAIN);
}
}
}
break;

Right now I am not a fan of how massive the switch statement for networking is, plus there is a lot of room for small errors that just desync the networking code. So I propose something like what is done for spells, where a number of singletons register with a service. Each singleton would contain the handlers for both a client receiving the message as well as the server.

This is being done in #39. But there's another issue that should be addressed as well - currently, each sending of a message over the network results in 3 packets being sent:
image
The first contains a single byte, which identifies the type of message.
The second is 4 bytes, and is the size of the following packet.
Finally, the last packet actually contains the data of the message.

This is obviously not ideal.

The bit from the previous comment is now fixed.

Fixed by #39.