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
+3
View File
@@ -34,6 +34,9 @@ public class Util {
public static double clamp(double input, double min, double max) {
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) {
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.ConstructScenery;
import java.util.Arrays;
/**
* A region chunk, used for easily modifying objects.
* @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.
*/
public static final int ARRAY_SIZE = 5;
public static final int ARRAY_SIZE = 10;
/**
* The list of changes made.
@@ -39,13 +41,17 @@ public class BuildRegionChunk extends RegionChunk {
public BuildRegionChunk(Location base, int rotation, RegionPlane plane) {
super(base, rotation, plane);
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) {
this.objects[0][x][y] = new Scenery(super.objects[x][y]);
}
}
}
}
public BuildRegionChunk(Location base, int rotation, RegionPlane plane, Scenery[][] objects) {
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
@@ -141,6 +147,22 @@ public class BuildRegionChunk extends RegionChunk {
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
public void clear() {
super.clear();
@@ -284,4 +306,19 @@ public class BuildRegionChunk extends RegionChunk {
public Scenery[][] getObjects(int 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.
*/
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;
}
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);
}
}
}
}
@@ -139,6 +139,10 @@ public final class RegionPlane {
}
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.
@@ -215,14 +215,18 @@ public final class DynamicRegion extends Region {
int regionX = ((regionId >> 8) & 0xFF) << 6;
int regionY = (regionId & 0xFF) << 6;
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 offsetY = 0; offsetY < 8; offsetY++) {
int x = regionX + (offsetX << 3);
int y = regionY + (offsetY << 3);
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) {
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.setBase(Location.create(x, y, plane));
@@ -330,41 +334,11 @@ public final class DynamicRegion extends Region {
}
}
} else {
chunk.clear();
Region.load(fromRegion);
Location l = chunk.getBase();
chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, 0));
Location regionBase = fromRegion.getBaseLocation();
RegionPlane rp = fromRegion.getPlanes()[l.getZ()];
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
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);
}
}
}
}
chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, z));
chunk.rebuildFlags(rp);
}
}
@@ -88,6 +88,22 @@ public final class LandscapeParser {
*/
public static void flagScenery(RegionPlane plane, int localX, int localY, Scenery object, boolean landscape, boolean storeObjects) {
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();
int sizeX;
int sizeY;
@@ -98,15 +114,6 @@ public final class LandscapeParser {
sizeX = def.sizeY;
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();
if (type == 22) { //Tile
plane.getFlags().getLandscape()[localX][localY] = true;
@@ -133,11 +140,9 @@ public final class LandscapeParser {
}
}
} else {
return;
}
if (!storeObjects && !add && (!def.getChildObject(null).getName().equals("null"))) {
addPlaneObject(plane, object, localX, localY, landscape, false);
return false;
}
return true;
}
/**
@@ -1,5 +1,6 @@
package core.net.packet.`in`
import core.Util.clamp
import core.game.node.entity.player.Player
import core.net.packet.IoBuffer
import core.tools.StringUtils
@@ -650,9 +651,11 @@ enum class Decoders530(val opcode: Int) {
},
CHAT_MESSAGE(237) {
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 message = StringUtils.decryptPlayerChat(buffer, numChars)
val effects = (effectPrefix shl 8) or effectSuffix
return Packet.ChatMessage(player, effects, message)
}
},