Improved handling of chat message packets

More improvements and fixes relating to dynamic regions and constructions
This commit is contained in:
Ceikry
2023-02-28 23:04:52 +00:00
committed by Ryan
parent dcaa980822
commit 5206c99151
9 changed files with 100 additions and 59 deletions
@@ -201,7 +201,6 @@ public final class BuildingUtils {
for (int i = 7; i >= 0; i--) { for (int i = 7; i >= 0; i--) {
Item can = player.getInventory().getItem(new Item(WATERING_CAN - i, 1)); Item can = player.getInventory().getItem(new Item(WATERING_CAN - i, 1));
if (can != null && can.getSlot() > -1) { if (can != null && can.getSlot() > -1) {
System.out.println("Can index " + (i == 7 ? i + 2 : i + 1) + ".");
player.getInventory().replace(new Item(WATERING_CAN - (i == 7 ? i + 2 : i + 1), 1), can.getSlot()); player.getInventory().replace(new Item(WATERING_CAN - (i == 7 ? i + 2 : i + 1), 1), can.getSlot());
break; break;
} }
@@ -396,10 +396,12 @@ public final class HouseManager {
houseRegion = getPreparedRegion(); houseRegion = getPreparedRegion();
configureRoofs(); configureRoofs();
prepareHouseChunks(style, houseRegion, buildingMode, rooms); prepareHouseChunks(style, houseRegion, buildingMode, rooms);
houseRegion.flagActive();
if (hasDungeon()) { if (hasDungeon()) {
dungeonRegion = getPreparedRegion(); dungeonRegion = getPreparedRegion();
prepareDungeonChunks(style, dungeonRegion, houseRegion, buildingMode, rooms[3]); prepareDungeonChunks(style, dungeonRegion, houseRegion, buildingMode, rooms[3]);
dungeonRegion.flagActive();
} }
ZoneBuilder.configure(zone); ZoneBuilder.configure(zone);
@@ -411,6 +413,7 @@ public final class HouseManager {
DynamicRegion region = new DynamicRegion(-1, borders.getSouthWestX() >> 6, borders.getSouthWestY() >> 6); DynamicRegion region = new DynamicRegion(-1, borders.getSouthWestX() >> 6, borders.getSouthWestY() >> 6);
region.setBorders(borders); region.setBorders(borders);
region.setUpdateAllPlanes(true); region.setUpdateAllPlanes(true);
region.setBuild(true);
RegionManager.addRegion(region.getId(), region); RegionManager.addRegion(region.getId(), region);
return region; return region;
} }
@@ -428,8 +431,7 @@ public final class HouseManager {
@Override @Override
public BuildRegionChunk getChunk(int x, int y, int plane, @NotNull DynamicRegion dyn) { public BuildRegionChunk getChunk(int x, int y, int plane, @NotNull DynamicRegion dyn) {
BuildRegionChunk chunk = rooms[plane][x][y].getChunk().copy(dyn.getPlanes()[plane]); return rooms[plane][x][y].getChunk().copy(dyn.getPlanes()[plane]);
return chunk;
} }
@Override @Override
+3
View File
@@ -34,6 +34,9 @@ public class Util {
public static double clamp(double input, double min, double max) { public static double clamp(double input, double min, double max) {
return Math.max(Math.min(input, max), min); return Math.max(Math.min(input, max), min);
} }
public static int clamp(int input, int min, int max) {
return Math.max(Math.min(input, max), min);
}
public static long nextMidnight(long currentTime) { public static long nextMidnight(long currentTime) {
Date date = new Date(); Date date = new Date();
@@ -13,6 +13,8 @@ import core.net.packet.out.ClearScenery;
import core.net.packet.out.ConstructGroundItem; import core.net.packet.out.ConstructGroundItem;
import core.net.packet.out.ConstructScenery; import core.net.packet.out.ConstructScenery;
import java.util.Arrays;
/** /**
* A region chunk, used for easily modifying objects. * A region chunk, used for easily modifying objects.
* @author Emperor * @author Emperor
@@ -23,7 +25,7 @@ public class BuildRegionChunk extends RegionChunk {
/** /**
* The maximum amount of objects to be stored on one tile in the chunk. * The maximum amount of objects to be stored on one tile in the chunk.
*/ */
public static final int ARRAY_SIZE = 5; public static final int ARRAY_SIZE = 10;
/** /**
* The list of changes made. * The list of changes made.
@@ -39,13 +41,17 @@ public class BuildRegionChunk extends RegionChunk {
public BuildRegionChunk(Location base, int rotation, RegionPlane plane) { public BuildRegionChunk(Location base, int rotation, RegionPlane plane) {
super(base, rotation, plane); super(base, rotation, plane);
this.objects = new Scenery[ARRAY_SIZE][8][8]; this.objects = new Scenery[ARRAY_SIZE][8][8];
for (int x = 0; x < SIZE; x++) { }
for (int y = 0; y < SIZE; y++) {
if(super.objects[x][y] != null) { public BuildRegionChunk(Location base, int rotation, RegionPlane plane, Scenery[][] objects) {
this.objects[0][x][y] = new Scenery(super.objects[x][y]); this(base, rotation, plane);
} for (int x = 0; x < SIZE; x++) {
} for (int y = 0; y < SIZE; y++) {
} if(objects[x][y] != null) {
this.objects[0][x][y] = new Scenery(objects[x][y]);
}
}
}
} }
@Override @Override
@@ -141,6 +147,22 @@ public class BuildRegionChunk extends RegionChunk {
return chunk; return chunk;
} }
@Override public void rebuildFlags(RegionPlane from) {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
Location loc = currentBase.transform(x,y,0);
Location fromLoc = base.transform(x,y,0);
plane.getFlags().getLandscape()[loc.getLocalX()][loc.getLocalY()] = from.getFlags().getLandscape()[fromLoc.getLocalX()][fromLoc.getLocalY()];
plane.getFlags().clearFlag(x, y);
for (int i = 0; i < ARRAY_SIZE; i++) {
Scenery obj = objects[i][x][y];
if (obj != null)
LandscapeParser.applyClippingFlagsFor(plane, loc.getLocalX(), loc.getLocalY(), obj);
}
}
}
}
@Override @Override
public void clear() { public void clear() {
super.clear(); super.clear();
@@ -284,4 +306,19 @@ public class BuildRegionChunk extends RegionChunk {
public Scenery[][] getObjects(int index) { public Scenery[][] getObjects(int index) {
return objects[index]; return objects[index];
} }
@Override
public void setCurrentBase(Location currentBase) {
for (int i = 0; i < objects.length; i++) {
for (int x = 0; x < objects[i].length; x++) {
for (int y = 0; y < objects[i][x].length; y++) {
if (objects[i][x][y] != null) {
Location newLoc = currentBase.transform(x, y, 0);
objects[i][x][y].setLocation(newLoc);
}
}
}
}
super.setCurrentBase(currentBase);
}
} }
@@ -83,7 +83,7 @@ public class RegionChunk {
* @return The region chunk. * @return The region chunk.
*/ */
public BuildRegionChunk copy(RegionPlane plane) { public BuildRegionChunk copy(RegionPlane plane) {
return new BuildRegionChunk(base, rotation, plane); return new BuildRegionChunk(base, rotation, plane, this.objects);
} }
/** /**
@@ -365,4 +365,18 @@ public class RegionChunk {
this.currentBase = currentBase; this.currentBase = currentBase;
} }
public void rebuildFlags(RegionPlane from) {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
Location loc = currentBase.transform(x,y,0);
Location fromLoc = base.transform(x,y,0);
plane.getFlags().getLandscape()[loc.getLocalX()][loc.getLocalY()] = from.getFlags().getLandscape()[fromLoc.getLocalX()][fromLoc.getLocalY()];
plane.getFlags().clearFlag(x, y);
Scenery obj = objects[x][y];
if (obj != null)
LandscapeParser.flagScenery(plane, loc.getLocalX(), loc.getLocalY(), obj, false, true);
}
}
}
} }
@@ -140,6 +140,10 @@ public final class RegionPlane {
return chunks[chunkX][chunkY] = new RegionChunk(region.getBaseLocation().transform(chunkX << 3, chunkY << 3, plane), 0, this); return chunks[chunkX][chunkY] = new RegionChunk(region.getBaseLocation().transform(chunkX << 3, chunkY << 3, plane), 0, this);
} }
public void setRegionChunk(int chunkX, int chunkY, RegionChunk chunk) {
chunks[chunkX][chunkY] = chunk;
}
/** /**
* Removes a scenery. * Removes a scenery.
* @param x The x-coordinate. * @param x The x-coordinate.
@@ -215,14 +215,18 @@ public final class DynamicRegion extends Region {
int regionX = ((regionId >> 8) & 0xFF) << 6; int regionX = ((regionId >> 8) & 0xFF) << 6;
int regionY = (regionId & 0xFF) << 6; int regionY = (regionId & 0xFF) << 6;
DynamicRegion region = new DynamicRegion(regionId, to.getRegionX() >> 3, to.getRegionY() >> 3); DynamicRegion region = new DynamicRegion(regionId, to.getRegionX() >> 3, to.getRegionY() >> 3);
Region base = RegionManager.forId(regionId);
Region.load(base);
for (int offsetX = 0; offsetX < 8; offsetX++) { for (int offsetX = 0; offsetX < 8; offsetX++) {
for (int offsetY = 0; offsetY < 8; offsetY++) { for (int offsetY = 0; offsetY < 8; offsetY++) {
int x = regionX + (offsetX << 3); int x = regionX + (offsetX << 3);
int y = regionY + (offsetY << 3); int y = regionY + (offsetY << 3);
for (int plane = 0; plane < 4; plane++) { for (int plane = 0; plane < 4; plane++) {
RegionChunk c = region.chunks[plane][offsetX][offsetY]; RegionChunk c = base.getPlanes()[plane].getRegionChunk(offsetX, offsetY);
if (c == null) { if (c == null) {
region.chunks[plane][offsetX][offsetY] = c = new RegionChunk(Location.create(0, 0, 0), 0, region.getPlanes()[plane]); region.chunks[plane][offsetX][offsetY] = c = new RegionChunk(Location.create(0, 0, 0), 0, region.getPlanes()[plane]);
} else {
region.replaceChunk(plane, offsetX, offsetY, (c = c.copy(region.getPlanes()[plane])), base);
} }
c.setRotation(0); c.setRotation(0);
c.setBase(Location.create(x, y, plane)); c.setBase(Location.create(x, y, plane));
@@ -330,41 +334,11 @@ public final class DynamicRegion extends Region {
} }
} }
} else { } else {
chunk.clear();
Region.load(fromRegion); Region.load(fromRegion);
Location l = chunk.getBase(); Location l = chunk.getBase();
chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, 0));
Location regionBase = fromRegion.getBaseLocation();
RegionPlane rp = fromRegion.getPlanes()[l.getZ()]; RegionPlane rp = fromRegion.getPlanes()[l.getZ()];
for (int i = 0; i < 8; i++) { chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, z));
for (int j = 0; j < 8; j++) { chunk.rebuildFlags(rp);
int toX = (x << 3) + i;
int toY = (y << 3) + j;
int fromX = (l.getX() - regionBase.getX()) + i;
int fromY = (l.getY() - regionBase.getY()) + j;
p.getFlags().getLandscape()[toX][toY] = rp.getFlags().getLandscape()[fromX][fromY];
p.getFlags().flag(fromX, fromY, rp.getFlags().getFlag(fromX, fromY));
p.getProjectileFlags().flag(fromX, fromY, rp.getFlags().getFlag(fromX, fromY));
Scenery[] objects = { rp.getChunkObject(fromX, fromY) };
RegionChunk ch = rp.getChunks()[fromX >> 3][fromY >> 3];
if (ch instanceof BuildRegionChunk) {
BuildRegionChunk bc = (BuildRegionChunk) ch;
objects = new Scenery[BuildRegionChunk.ARRAY_SIZE];
for (int k = 0; k < objects.length; k++) {
objects[k] = bc.get(i, j, k);
}
}
for (Scenery object : objects) {
if (object != null) {
object = object.transform(object.getId(), object.getRotation(), getBaseLocation().transform(toX, toY, 0));
LandscapeParser.flagScenery(p, toX, toY, object, false, true);//chunk instanceof BuildRegionChunk);//.addGameObject(object, true);
} else {
p.add(null, toX, toY, true);
}
}
}
}
} }
} }
@@ -88,6 +88,22 @@ public final class LandscapeParser {
*/ */
public static void flagScenery(RegionPlane plane, int localX, int localY, Scenery object, boolean landscape, boolean storeObjects) { public static void flagScenery(RegionPlane plane, int localX, int localY, Scenery object, boolean landscape, boolean storeObjects) {
Region.load(plane.getRegion()); Region.load(plane.getRegion());
SceneryDefinition def = object.getDefinition();
object.setActive(true);
boolean add = storeObjects || !landscape || def.getChildObject(null).hasActions();
if (add) {
addPlaneObject(plane, object, localX, localY, landscape, storeObjects);
}
if (!applyClippingFlagsFor(plane, localX, localY, object))
return;
if (!storeObjects && !add && (!def.getChildObject(null).getName().equals("null"))) {
addPlaneObject(plane, object, localX, localY, landscape, false);
}
}
public static boolean applyClippingFlagsFor(RegionPlane plane, int localX, int localY, Scenery object) {
SceneryDefinition def = object.getDefinition(); SceneryDefinition def = object.getDefinition();
int sizeX; int sizeX;
int sizeY; int sizeY;
@@ -98,15 +114,6 @@ public final class LandscapeParser {
sizeX = def.sizeY; sizeX = def.sizeY;
sizeY = def.sizeX; sizeY = def.sizeX;
} }
object.setActive(true);
boolean add = storeObjects || !landscape || def.getChildObject(null).hasActions();
if (add) {
addPlaneObject(plane, object, localX, localY, landscape, storeObjects);
}
// if (localX == 34 && localY == 32 && plane.getRegion().getId() == 14746) {
// System.out.println(object + ", " + Arrays.toString(object.getDefinition().getOptions()) + ", " + object.getDefinition().projectileClipped);
// }
int type = object.getType(); int type = object.getType();
if (type == 22) { //Tile if (type == 22) { //Tile
plane.getFlags().getLandscape()[localX][localY] = true; plane.getFlags().getLandscape()[localX][localY] = true;
@@ -133,11 +140,9 @@ public final class LandscapeParser {
} }
} }
} else { } else {
return; return false;
}
if (!storeObjects && !add && (!def.getChildObject(null).getName().equals("null"))) {
addPlaneObject(plane, object, localX, localY, landscape, false);
} }
return true;
} }
/** /**
@@ -1,5 +1,6 @@
package core.net.packet.`in` package core.net.packet.`in`
import core.Util.clamp
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.net.packet.IoBuffer import core.net.packet.IoBuffer
import core.tools.StringUtils import core.tools.StringUtils
@@ -650,9 +651,11 @@ enum class Decoders530(val opcode: Int) {
}, },
CHAT_MESSAGE(237) { CHAT_MESSAGE(237) {
override fun decode(player: Player, buffer: IoBuffer): Packet { override fun decode(player: Player, buffer: IoBuffer): Packet {
val effects = buffer.short val effectPrefix = clamp(buffer.get(), 0, 11)
val effectSuffix = clamp(buffer.get(), 0, 5)
val numChars = buffer.smart val numChars = buffer.smart
val message = StringUtils.decryptPlayerChat(buffer, numChars) val message = StringUtils.decryptPlayerChat(buffer, numChars)
val effects = (effectPrefix shl 8) or effectSuffix
return Packet.ChatMessage(player, effects, message) return Packet.ChatMessage(player, effects, message)
} }
}, },