The structure list comes from a HashSet, so its order was never fixed: positive UIDs happened to put a parent before its children, negative static IDs put the children first. Live recordings send the parent first in all 2,365 parent/child pairs within one record (none the other way); the citadel-test recording had all 616 children first, and the Citadel of War's upper-floor table and chairs (CZONE Y 27, sent correctly) showed on the ground floor. Top-level buildings are now written first, then children. Value changes: record order only; every field is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
108 lines
3.3 KiB
Java
108 lines
3.3 KiB
Java
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
|
// Magicbane Emulator Project © 2013 - 2026
|
|
// https://www.magicbane.com
|
|
|
|
|
|
package engine.net.client.msg;
|
|
|
|
|
|
import engine.net.*;
|
|
import engine.objects.Building;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
public class LoadStructureMsg extends ClientNetMsg {
|
|
|
|
private ArrayList<Building> structureList;
|
|
|
|
/**
|
|
* This is the general purpose constructor.
|
|
*/
|
|
public LoadStructureMsg() {
|
|
this(new ArrayList<>());
|
|
}
|
|
|
|
/**
|
|
* This is the general purpose constructor.
|
|
*
|
|
* @param structures
|
|
*/
|
|
public LoadStructureMsg(ArrayList<Building> structures) {
|
|
super(Protocol.LOADSTRUCTURE);
|
|
this.structureList = structures;
|
|
}
|
|
|
|
/**
|
|
* This constructor is used by NetMsgFactory. It attempts to deserialize the
|
|
* ByteBuffer into a message. If a BufferUnderflow occurs (based on reading
|
|
* past the limit) then this constructor Throws that Exception to the
|
|
* caller.
|
|
*/
|
|
public LoadStructureMsg(AbstractConnection origin, ByteBufferReader reader) {
|
|
super(Protocol.LOADSTRUCTURE, origin, reader);
|
|
}
|
|
|
|
/**
|
|
* @see AbstractNetMsg#getPowerOfTwoBufferSize()
|
|
*/
|
|
@Override
|
|
protected int getPowerOfTwoBufferSize() {
|
|
//Larger size for historically larger opcodes
|
|
return (18); // 2^16 == 64k
|
|
}
|
|
|
|
/**
|
|
* Serializes the subclass specific items to the supplied NetMsgWriter.
|
|
*/
|
|
@Override
|
|
protected void _serialize(ByteBufferWriter writer) {
|
|
for (int i = 0; i < 4; i++)
|
|
writer.putInt(0);
|
|
|
|
writer.putInt(this.structureList.size());
|
|
|
|
// Parents before children, as live servers sent them; a child sent first loses its height on the client.
|
|
|
|
for (Building building : this.structureList)
|
|
if (building.parentBuildingID == 0)
|
|
Building._serializeForClientMsg(building, writer);
|
|
|
|
for (Building building : this.structureList)
|
|
if (building.parentBuildingID != 0)
|
|
Building._serializeForClientMsg(building, writer);
|
|
|
|
writer.putInt(0);
|
|
}
|
|
|
|
/**
|
|
* Deserializes the subclass specific items from the supplied NetMsgReader.
|
|
*/
|
|
@Override
|
|
protected void _deserialize(ByteBufferReader reader) {
|
|
reader.getInt();
|
|
reader.getInt();
|
|
reader.getInt();
|
|
reader.getInt();
|
|
int size = reader.getInt();
|
|
// TODO finish Deserialize impl
|
|
}
|
|
|
|
// TODO fix ArrayList Accessability.
|
|
public ArrayList<Building> getStructureList() {
|
|
return this.structureList;
|
|
}
|
|
|
|
public void addObject(Building obj) {
|
|
this.structureList.add(obj);
|
|
}
|
|
|
|
public int size() {
|
|
return this.structureList.size();
|
|
}
|
|
}
|