diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/HFloorItem.java b/G-Earth/src/main/java/gearth/extensions/parsers/HFloorItem.java index 71ffda6..a6ae8b6 100644 --- a/G-Earth/src/main/java/gearth/extensions/parsers/HFloorItem.java +++ b/G-Earth/src/main/java/gearth/extensions/parsers/HFloorItem.java @@ -1,10 +1,9 @@ package gearth.extensions.parsers; +import gearth.extensions.parsers.stuffdata.IStuffData; import gearth.protocol.HPacket; import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; public class HFloorItem implements IFurni { private int id; @@ -12,17 +11,15 @@ public class HFloorItem implements IFurni { private HPoint tile; private HDirection facing; - private int category; - private int secondsToExpiration; private int usagePolicy; private int ownerId; private String ownerName; - private Object[] stuff; + private IStuffData stuff; - private String ignore1; - private Integer ignore2; - private String ignore3; + private String sizeZ; + private Integer extra; + private String staticClass; public HFloorItem(HPacket packet) { id = packet.readInteger(); @@ -34,12 +31,10 @@ public class HFloorItem implements IFurni { tile = new HPoint(x, y, Double.parseDouble(packet.readString())); - ignore1 = packet.readString(); - ignore2 = packet.readInteger(); + sizeZ = packet.readString(); + extra = packet.readInteger(); - category = packet.readInteger(); - - stuff = HStuff.readData(packet, category); + stuff = IStuffData.read(packet); secondsToExpiration = packet.readInteger(); usagePolicy = packet.readInteger(); @@ -47,13 +42,11 @@ public class HFloorItem implements IFurni { ownerId = packet.readInteger(); if (typeId < 0) { - ignore3 = packet.readString(); + staticClass = packet.readString(); } else { - ignore3 = null; + staticClass = null; } - - } public void appendToPacket(HPacket packet) { @@ -76,20 +69,14 @@ public class HFloorItem implements IFurni { packet.appendString(tile.getZ() + ""); -// ignore1 = packet.readString(); - packet.appendString(ignore1); +// sizeZ = packet.readString(); + packet.appendString(sizeZ); -// ignore2 = packet.readInteger(); - packet.appendInt(ignore2); +// extra = packet.readInteger(); + packet.appendInt(extra); -// category = packet.readInteger(); - packet.appendInt(category); - - -// stuff = HStuff.readData(packet, category); - for (Object object : stuff) { - packet.appendObject(object); - } +// stuff = IStuffData.read(packet); + stuff.appendToPacket(packet); // secondsToExpiration = packet.readInteger(); packet.appendInt(secondsToExpiration); @@ -102,8 +89,8 @@ public class HFloorItem implements IFurni { if (typeId < 0) { - // ignore3 = packet.readString(); - packet.appendString(ignore3); + // staticClass = packet.readString(); + packet.appendString(staticClass); } } @@ -174,9 +161,9 @@ public class HFloorItem implements IFurni { return secondsToExpiration; } - public int getCategory() { - return category; - } +// public int getCategory() { +// return category; +// } public HDirection getFacing() { return facing; @@ -186,7 +173,7 @@ public class HFloorItem implements IFurni { return tile; } - public Object[] getStuff() { + public IStuffData getStuff() { return stuff; } @@ -210,9 +197,9 @@ public class HFloorItem implements IFurni { this.facing = facing; } - public void setCategory(int category) { - this.category = category; - } +// public void setCategory(int category) { +// this.category = category; +// } public void setSecondsToExpiration(int secondsToExpiration) { this.secondsToExpiration = secondsToExpiration; @@ -226,7 +213,7 @@ public class HFloorItem implements IFurni { this.ownerId = ownerId; } - public void setStuff(Object[] stuff) { + public void setStuff(IStuffData stuff) { this.stuff = stuff; } } diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/HInventoryItem.java b/G-Earth/src/main/java/gearth/extensions/parsers/HInventoryItem.java index 89888d6..3efe139 100644 --- a/G-Earth/src/main/java/gearth/extensions/parsers/HInventoryItem.java +++ b/G-Earth/src/main/java/gearth/extensions/parsers/HInventoryItem.java @@ -1,5 +1,6 @@ package gearth.extensions.parsers; +import gearth.extensions.parsers.stuffdata.IStuffData; import gearth.protocol.HPacket; public class HInventoryItem { @@ -8,8 +9,7 @@ public class HInventoryItem { private int id; private int typeId; private HSpecialType specialType; - private int category; - private Object[] stuff; + private IStuffData stuff; private boolean recyclable; private boolean tradeable; private boolean groupable; @@ -27,8 +27,7 @@ public class HInventoryItem { id = packet.readInteger(); typeId = packet.readInteger(); specialType = HSpecialType.fromId(packet.readInteger()); - category = packet.readInteger(); - stuff = HStuff.readData(packet, category); + stuff = IStuffData.read(packet); recyclable = packet.readBoolean(); tradeable = packet.readBoolean(); groupable = packet.readBoolean(); @@ -49,11 +48,7 @@ public class HInventoryItem { packet.appendInt(id); packet.appendInt(typeId); packet.appendInt(specialType.getId()); - packet.appendInt(category); - - for (Object object : stuff) { - packet.appendObject(object); - } + stuff.appendToPacket(packet); packet.appendBoolean(recyclable); packet.appendBoolean(tradeable); @@ -133,19 +128,11 @@ public class HInventoryItem { this.typeId = typeId; } - public int getCategory() { - return category; - } - - public void setCategory(int category) { - this.category = category; - } - - public Object[] getStuff() { + public IStuffData getStuff() { return stuff; } - public void setStuff(Object[] stuff) { + public void setStuff(IStuffData stuff) { this.stuff = stuff; } diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/HStuff.java b/G-Earth/src/main/java/gearth/extensions/parsers/HStuff.java deleted file mode 100644 index 041a93e..0000000 --- a/G-Earth/src/main/java/gearth/extensions/parsers/HStuff.java +++ /dev/null @@ -1,91 +0,0 @@ -package gearth.extensions.parsers; - -import gearth.protocol.HPacket; - -import java.util.ArrayList; -import java.util.List; - -public class HStuff { - - public static Object[] readData(HPacket packet, int category) { - List values = new ArrayList<>(); - switch (category & 0xFF) - { - case 0: /* LegacyStuffData */ { - values.add(packet.readString()); - break; - } - case 1: /* MapStuffData */ { - int count = packet.readInteger(); - values.add(count); - - for (int j = 0; j < count; j++) - { - values.add(packet.readString()); - values.add(packet.readString()); - } - break; - } - case 2: /* StringArrayStuffData */ { - int count = packet.readInteger(); - values.add(count); - - for (int j = 0; j < count; j++) - { - values.add(packet.readString()); - } - break; - } - case 3: /* VoteResultStuffData */ { - values.add(packet.readString()); - values.add(packet.readInteger()); - break; - } - case 5: /* IntArrayStuffData */ { - int count = packet.readInteger(); - values.add(count); - - for (int j = 0; j < count; j++) - { - values.add(packet.readInteger()); - } - break; - } - case 6: /* HighScoreStuffData */ { - values.add(packet.readString()); - values.add(packet.readInteger()); - values.add(packet.readInteger()); - - int count = packet.readInteger(); - values.add(count); - - for (int j = 0; j < count; j++) - { - int score = packet.readInteger(); - values.add(score); - - int subCount = packet.readInteger(); - values.add(subCount); - - for (int k = 0; k < subCount; k++) - { - values.add(packet.readString()); - } - } - break; - } - case 7: /* CrackableStuffData */ { - values.add(packet.readString()); - values.add(packet.readInteger()); - values.add(packet.readInteger()); - break; - } - } - if ((category & 0xFF00 & 0x100) > 0) { - values.add(packet.readInteger()); - values.add(packet.readInteger()); - } - return values.toArray(); - } - -} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/ArrayStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/ArrayStuffData.java new file mode 100644 index 0000000..f899cc5 --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/ArrayStuffData.java @@ -0,0 +1,173 @@ +package gearth.extensions.parsers.stuffdata; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.Stream; + +/** + * Wrapper class to make IntArrayStuffData and StringArrayStuffData behave like a List + * @param Value class + */ +public class ArrayStuffData extends StuffDataBase implements List { + protected List values = new ArrayList<>(); + + public ArrayStuffData() { + super(); + } + + public ArrayStuffData(int uniqueSerialNumber, int uniqueSerialSize) { + super(uniqueSerialNumber, uniqueSerialSize); + } + + @Override + public int size() { + return values.size(); + } + + @Override + public boolean isEmpty() { + return values.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return values.contains(o); + } + + @Override + public Iterator iterator() { + return values.iterator(); + } + + @Override + public void forEach(Consumer action) { + values.forEach(action); + } + + @Override + public Object[] toArray() { + return values.toArray(); + } + + @Override + public T1[] toArray(T1[] a) { + return values.toArray(a); + } + + @Override + public boolean add(T t) { + return values.add(t); + } + + @Override + public boolean remove(Object o) { + return values.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return values.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return values.addAll(c); + } + + @Override + public boolean addAll(int index, Collection c) { + return values.addAll(index, c); + } + + @Override + public boolean removeAll(Collection c) { + return values.removeAll(c); + } + + @Override + public boolean removeIf(Predicate filter) { + return values.removeIf(filter); + } + + @Override + public boolean retainAll(Collection c) { + return values.retainAll(c); + } + + @Override + public void replaceAll(UnaryOperator operator) { + values.replaceAll(operator); + } + + @Override + public void sort(Comparator c) { + values.sort(c); + } + + @Override + public void clear() { + values.clear(); + } + + @Override + public T get(int index) { + return values.get(index); + } + + @Override + public T set(int index, T element) { + return values.set(index, element); + } + + @Override + public void add(int index, T element) { + values.add(index, element); + } + + @Override + public T remove(int index) { + return values.remove(index); + } + + @Override + public int indexOf(Object o) { + return values.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return values.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + return values.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + return values.listIterator(index); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return values.subList(fromIndex, toIndex); + } + + @Override + public Spliterator spliterator() { + return values.spliterator(); + } + + @Override + public Stream stream() { + return values.stream(); + } + + @Override + public Stream parallelStream() { + return values.parallelStream(); + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/CrackableStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/CrackableStuffData.java new file mode 100644 index 0000000..2e4afb5 --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/CrackableStuffData.java @@ -0,0 +1,73 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +public class CrackableStuffData extends StuffDataBase { + public final static int IDENTIFIER = 7; + + private String legacyString = ""; + private int hits = 0; + private int target = 0; + + protected CrackableStuffData() {} + + public CrackableStuffData(String legacyString, int hits, int target) { + super(); + this.legacyString = legacyString == null ? "" : legacyString; + this.hits = hits; + this.target = target; + } + + + public CrackableStuffData(int uniqueSerialNumber, int uniqueSerialSize, String legacyString, int hits, int target) { + super(uniqueSerialNumber, uniqueSerialSize); + this.legacyString = legacyString == null ? "" : legacyString; + this.hits = hits; + this.target = target; + } + + @Override + protected void initialize(HPacket packet) { + this.legacyString = packet.readString(); + this.hits = packet.readInteger(); + this.target = packet.readInteger(); + super.initialize(packet); + } + + @Override + public void appendToPacket(HPacket packet) { + packet.appendInt(IDENTIFIER | this.getFlags()); + packet.appendObjects( + this.legacyString, + this.hits, + this.target + ); + super.appendToPacket(packet); + } + + @Override + public String getLegacyString() { + return this.legacyString; + } + + @Override + public void setLegacyString(String legacyString) { + this.legacyString = legacyString; + } + + public int getHits() { + return this.hits; + } + + public void setHits(int hits) { + this.hits = hits; + } + + public int getTarget() { + return this.target; + } + + public void setTarget(int target) { + this.target = target; + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/EmptyStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/EmptyStuffData.java new file mode 100644 index 0000000..a54b3e6 --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/EmptyStuffData.java @@ -0,0 +1,26 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +public class EmptyStuffData extends StuffDataBase { + public final static int IDENTIFIER = 4; + + public EmptyStuffData() { + super(); + } + + public EmptyStuffData(int uniqueSerialNumber, int uniqueSerialSize) { + super(uniqueSerialNumber, uniqueSerialSize); + } + + @Override + protected void initialize(HPacket packet) { + super.initialize(packet); + } + + @Override + public void appendToPacket(HPacket packet) { + packet.appendInt(IDENTIFIER | this.getFlags()); + super.appendToPacket(packet); + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/HighScoreData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/HighScoreData.java new file mode 100644 index 0000000..5089370 --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/HighScoreData.java @@ -0,0 +1,53 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +import java.util.Arrays; +import java.util.Objects; + +public class HighScoreData { + private int score; + private String[] users; + + protected HighScoreData(HPacket packet) { + this.score = packet.readInteger(); + int size = packet.readInteger(); + this.users = new String[size]; + for (int i = 0; i < size; i++) { + this.users[i] = packet.readString(); + } + } + + public HighScoreData(int score, String... users) { + super(); + this.score = score; + this.users = Arrays.stream(users).filter(Objects::nonNull).toArray(String[]::new); + } + + protected void appendToPacket(HPacket packet) { + packet.appendInt(this.score); + packet.appendInt(this.users.length); + for (String user : this.users) { + packet.appendString(user); + } + } + + public int getScore() { + return this.score; + } + + public void setScore(int score) { + this.score = score; + } + + public String[] getUsers() { + return this.users.clone(); + } + + public void setUsers(String[] users) { + this.users = Arrays + .stream(users == null ? new String[0] : users) + .filter(Objects::nonNull) + .toArray(String[]::new); + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/HighScoreStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/HighScoreStuffData.java new file mode 100644 index 0000000..bd47998 --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/HighScoreStuffData.java @@ -0,0 +1,99 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +import java.util.Arrays; +import java.util.Objects; + +public class HighScoreStuffData extends StuffDataBase { + public final static int IDENTIFIER = 6; + + private String legacyString = ""; + // ['perteam', 'mostwins', 'classic', 'fastesttime', 'longesttime'] + private int scoreType = 0; + // ['alltime', 'daily', 'weekly', 'monthly'] + private int clearType = 0; + private HighScoreData[] entries = {}; + + protected HighScoreStuffData() {} + + public HighScoreStuffData(String legacyString, int scoreType, int clearType, HighScoreData... entries) { + super(); + this.legacyString = legacyString == null ? "" : legacyString; + this.scoreType = scoreType; + this.clearType = clearType; + this.entries = Arrays.stream(entries).filter(Objects::nonNull).toArray(HighScoreData[]::new); + } + + public HighScoreStuffData(int uniqueSerialNumber, int uniqueSerialSize, String legacyString, int scoreType, int clearType, HighScoreData... entries) { + super(uniqueSerialNumber, uniqueSerialSize); + this.legacyString = legacyString == null ? "" : legacyString; + this.scoreType = scoreType; + this.clearType = clearType; + this.entries = Arrays.stream(entries).filter(Objects::nonNull).toArray(HighScoreData[]::new); + } + + @Override + protected void initialize(HPacket packet) { + this.legacyString = packet.readString(); + this.scoreType = packet.readInteger(); + this.clearType = packet.readInteger(); + + int size = packet.readInteger(); + this.entries = new HighScoreData[size]; + for (int i = 0; i < size; i++) { + this.entries[i] = new HighScoreData(packet); + } + } + + @Override + public void appendToPacket(HPacket packet) { + packet.appendInt(IDENTIFIER | this.getFlags()); + packet.appendObjects( + this.legacyString, + this.scoreType, + this.clearType, + this.entries.length + ); + for (HighScoreData entry : this.entries) { + entry.appendToPacket(packet); + } + } + + @Override + public String getLegacyString() { + return this.legacyString; + } + + @Override + public void setLegacyString(String legacyString) { + this.legacyString = legacyString; + } + + public int getScoreType() { + return this.scoreType; + } + + public void setScoreType(int scoreType) { + this.scoreType = scoreType; + } + + public int getClearType() { + return this.clearType; + } + + public void setClearType(int clearType) { + this.clearType = clearType; + } + + public HighScoreData[] getEntries() { + return this.entries.clone(); + } + + public void setEntries(HighScoreData[] entries) { + this.entries = Arrays + .stream(entries == null ? new HighScoreData[0] : entries) + .filter(Objects::nonNull) + .toArray(HighScoreData[]::new); + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/IStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/IStuffData.java new file mode 100644 index 0000000..7a1dd7a --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/IStuffData.java @@ -0,0 +1,66 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +public interface IStuffData { + static IStuffData read(HPacket packet) { + int a = packet.readInteger(); + StuffDataBase stuffData = null; + + switch (a & 255) { + case LegacyStuffData.IDENTIFIER: + stuffData = new LegacyStuffData(); + break; + case MapStuffData.IDENTIFIER: + stuffData = new MapStuffData(); + break; + case StringArrayStuffData.IDENTIFIER: + stuffData = new StringArrayStuffData(); + break; + case VoteResultStuffData.IDENTIFIER: + stuffData = new VoteResultStuffData(); + break; + case EmptyStuffData.IDENTIFIER: + stuffData = new EmptyStuffData(); + break; + case IntArrayStuffData.IDENTIFIER: + stuffData = new IntArrayStuffData(); + break; + case HighScoreStuffData.IDENTIFIER: + stuffData = new HighScoreStuffData(); + break; + case CrackableStuffData.IDENTIFIER: + stuffData = new CrackableStuffData(); + break; + } + + if (stuffData != null) { + stuffData.setFlags(a & 65280); + stuffData.initialize(packet); + } else { + throw new RuntimeException("Unknown stuffdata type"); + } + + return stuffData; + } + + void appendToPacket(HPacket packet); + + String getLegacyString(); + void setLegacyString(String legacyString); + + void setFlags(int flags); + int getFlags(); + + int getUniqueSerialNumber(); + int getUniqueSerialSize(); + void setUniqueSerialNumber(int uniqueSerialNumber); + void setUniqueSerialSize(int uniqueSerialSize); + + int getRarityLevel(); + + int getState(); + void setState(int state); + + String getJSONValue(String key); +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/IntArrayStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/IntArrayStuffData.java new file mode 100644 index 0000000..0976381 --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/IntArrayStuffData.java @@ -0,0 +1,53 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +import java.util.Arrays; + +// 5 +public class IntArrayStuffData extends ArrayStuffData { + public final static int IDENTIFIER = 5; + + protected IntArrayStuffData() {} + + public IntArrayStuffData(Integer... values) { + super(); + this.values = Arrays.asList(values); + } + + public IntArrayStuffData(int uniqueSerialNumber, int uniqueSerialSize, Integer... values) { + super(uniqueSerialNumber, uniqueSerialSize); + this.values = Arrays.asList(values); + } + + @Override + protected void initialize(HPacket packet) { + int size = packet.readInteger(); + this.clear(); + for (int i = 0; i < size; i++) { + this.add(packet.readInteger()); + } + super.initialize(packet); + } + + @Override + public void appendToPacket(HPacket packet) { + packet.appendInt(IDENTIFIER | this.getFlags()); + packet.appendInt(this.size()); + for (int i : this) { + packet.appendInt(i); + } + super.appendToPacket(packet); + } + + @Override + public String getLegacyString() { + return this.size() > 0 ? String.valueOf(this.get(0)) : ""; + } + + @Override + public void setLegacyString(String legacyString) { + if (this.size() > 0) + this.set(0, Integer.parseInt(legacyString)); + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/LegacyStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/LegacyStuffData.java new file mode 100644 index 0000000..f043d4d --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/LegacyStuffData.java @@ -0,0 +1,43 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +public class LegacyStuffData extends StuffDataBase { + public final static int IDENTIFIER = 0; + + private String legacyString; + + protected LegacyStuffData() {} + + public LegacyStuffData(String legacyString) { + this.legacyString = legacyString == null ? "" : legacyString; + } + + public LegacyStuffData(int uniqueSerialNumber, int uniqueSerialSize, String legacyString) { + super(uniqueSerialNumber, uniqueSerialSize); + this.legacyString = legacyString == null ? "" : legacyString; + } + + @Override + protected void initialize(HPacket packet) { + this.legacyString = packet.readString(); + super.initialize(packet); + } + + @Override + public void appendToPacket(HPacket packet) { + packet.appendInt(IDENTIFIER | this.getFlags()); + packet.appendString(this.legacyString); + super.appendToPacket(packet); + } + + @Override + public String getLegacyString() { + return this.legacyString; + } + + @Override + public void setLegacyString(String legacyString) { + this.legacyString = legacyString; + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/MapStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/MapStuffData.java new file mode 100644 index 0000000..8d025a0 --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/MapStuffData.java @@ -0,0 +1,177 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class MapStuffData extends StuffDataBase implements Map { + public final static int IDENTIFIER = 1; + + private Map map = new HashMap<>(); + + protected MapStuffData() {} + + public MapStuffData(HashMap map) { + this.map = map == null ? new HashMap<>() : map.entrySet().stream().filter(e -> e.getValue() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, HashMap::new)); + } + + public MapStuffData(int uniqueSerialNumber, int uniqueSerialSize, HashMap map) { + super(uniqueSerialNumber, uniqueSerialSize); + this.map = map == null ? new HashMap<>() : map.entrySet().stream().filter(e -> e.getValue() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, HashMap::new)); + } + + @Override + protected void initialize(HPacket packet) { + int size = packet.readInteger(); + this.clear(); + for (int i = 0; i < size; i++) { + this.put(packet.readString(), packet.readString()); + } + super.initialize(packet); + } + + @Override + public void appendToPacket(HPacket packet) { + packet.appendInt(IDENTIFIER | this.getFlags()); + packet.appendInt(this.size()); + for (Entry entry : this.entrySet()) { + packet.appendObjects( + entry.getKey(), + entry.getValue() == null ? "" : entry.getValue() + ); + } + super.appendToPacket(packet); + } + + @Override + public String getLegacyString() { + return this.getOrDefault("state", ""); + } + + @Override + public void setLegacyString(String legacyString) { + this.put("state", legacyString == null ? "" : legacyString); + } + + @Override + public int size() { + return this.map.size(); + } + + @Override + public boolean isEmpty() { + return this.map.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return this.map.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return this.map.containsValue(value); + } + + @Override + public String get(Object key) { + return this.map.get(key); + } + + @Override + public String put(String key, String value) { + return this.map.put(key, value); + } + + @Override + public String remove(Object key) { + return this.map.remove(key); + } + + @Override + public void putAll(Map m) { + this.map.putAll(m); + } + + @Override + public void clear() { + this.map.clear(); + } + + @Override + public Set keySet() { + return this.map.keySet(); + } + + @Override + public Collection values() { + return this.map.values(); + } + + @Override + public Set> entrySet() { + return this.map.entrySet(); + } + + @Override + public String getOrDefault(Object key, String defaultValue) { + return this.map.getOrDefault(key, defaultValue); + } + + @Override + public void forEach(BiConsumer action) { + this.map.forEach(action); + } + + @Override + public void replaceAll(BiFunction function) { + this.map.replaceAll(function); + } + + @Override + public String putIfAbsent(String key, String value) { + return this.map.putIfAbsent(key, value); + } + + @Override + public boolean remove(Object key, Object value) { + return this.map.remove(key, value); + } + + @Override + public boolean replace(String key, String oldValue, String newValue) { + return this.map.replace(key, oldValue, newValue); + } + + @Override + public String replace(String key, String value) { + return this.map.replace(key, value); + } + + @Override + public String computeIfAbsent(String key, Function mappingFunction) { + return this.map.computeIfAbsent(key, mappingFunction); + } + + @Override + public String computeIfPresent(String key, BiFunction remappingFunction) { + return this.map.computeIfPresent(key, remappingFunction); + } + + @Override + public String compute(String key, BiFunction remappingFunction) { + return this.map.compute(key, remappingFunction); + } + + @Override + public String merge(String key, String value, BiFunction remappingFunction) { + return this.map.merge(key, value, remappingFunction); + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/StringArrayStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/StringArrayStuffData.java new file mode 100644 index 0000000..4cce9fd --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/StringArrayStuffData.java @@ -0,0 +1,55 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +// 2 +public class StringArrayStuffData extends ArrayStuffData { + public final static int IDENTIFIER = 2; + + protected StringArrayStuffData() {} + + public StringArrayStuffData(String... array) { + this.values = Arrays.stream(array).filter(Objects::nonNull).collect(Collectors.toList()); + } + + public StringArrayStuffData(int uniqueSerialNumber, int uniqueSerialSize, String... array) { + super(uniqueSerialNumber, uniqueSerialSize); + this.values = Arrays.stream(array).filter(Objects::nonNull).collect(Collectors.toList()); + } + + @Override + protected void initialize(HPacket packet) { + int size = packet.readInteger(); + this.clear(); + for (int i = 0; i < size; i++) { + this.add(packet.readString()); + } + super.initialize(packet); + } + + @Override + public void appendToPacket(HPacket packet) { + packet.appendInt(IDENTIFIER | this.getFlags()); + packet.appendInt(this.size()); + for (String s : this) { + packet.appendString(s); + } + super.appendToPacket(packet); + } + + @Override + public String getLegacyString() { + return this.size() > 0 ? this.get(0) : ""; + } + + @Override + public void setLegacyString(String legacyString) { + if (this.size() > 0) { + this.set(0, legacyString == null ? "" : legacyString); + } + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/StuffDataBase.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/StuffDataBase.java new file mode 100644 index 0000000..04fe7a2 --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/StuffDataBase.java @@ -0,0 +1,98 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; +import org.json.JSONObject; + +public abstract class StuffDataBase implements IStuffData { + private int flags = 0; + private int uniqueSerialNumber = 0; + private int uniqueSerialSize = 0; + + protected StuffDataBase() {} + + protected StuffDataBase(int uniqueSerialNumber, int uniqueSerialSize) { + this.uniqueSerialNumber = uniqueSerialNumber; + this.uniqueSerialSize = uniqueSerialSize; + flags = 256; + } + + protected void initialize(HPacket packet) { + if ((flags & 256) > 0) { + this.uniqueSerialNumber = packet.readInteger(); + this.uniqueSerialSize = packet.readInteger(); + } + } + + public void appendToPacket(HPacket packet) { + if ((flags & 256) > 0) { + packet.appendInt(this.uniqueSerialNumber); + packet.appendInt(this.uniqueSerialSize); + } + } + + @Override + public String getLegacyString() { + return ""; + } + + @Override + public void setLegacyString(String legacyString) {} + + @Override + public final void setFlags(int flags) { + this.flags = flags; + } + + @Override + public final int getFlags() { + return this.flags; + } + + @Override + public final int getUniqueSerialNumber() { + return this.uniqueSerialNumber; + } + + @Override + public final int getUniqueSerialSize() { + return this.uniqueSerialSize; + } + + @Override + public final void setUniqueSerialNumber(int uniqueSerialNumber) { + this.uniqueSerialNumber = uniqueSerialNumber; + } + + @Override + public final void setUniqueSerialSize(int uniqueSerialSize) { + this.uniqueSerialSize = uniqueSerialSize; + } + + @Override + public int getRarityLevel() { + return -1; + } + + @Override + public final int getState() { + try { + return Integer.parseInt(getLegacyString()); + } catch (Exception e) { + return -1; + } + } + + @Override + public final void setState(int state) { + setLegacyString(String.valueOf(state)); + } + + @Override + public final String getJSONValue(String key) { + try { + return new JSONObject(getLegacyString()).getString(key); + } catch (Exception e) { + return ""; + } + } +} diff --git a/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/VoteResultStuffData.java b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/VoteResultStuffData.java new file mode 100644 index 0000000..b3de3a4 --- /dev/null +++ b/G-Earth/src/main/java/gearth/extensions/parsers/stuffdata/VoteResultStuffData.java @@ -0,0 +1,58 @@ +package gearth.extensions.parsers.stuffdata; + +import gearth.protocol.HPacket; + +public class VoteResultStuffData extends StuffDataBase { + public static final int IDENTIFIER = 3; + + private String legacyString = ""; + private int result = 0; + + protected VoteResultStuffData() {} + + public VoteResultStuffData(String legacyString, int result) { + this.legacyString = legacyString == null ? "" : legacyString; + this.result = result; + } + + public VoteResultStuffData(int uniqueSerialNumber, int uniqueSerialSize, String legacyString, int result) { + super(uniqueSerialNumber, uniqueSerialSize); + this.legacyString = legacyString == null ? "" : legacyString; + this.result = result; + } + + @Override + protected void initialize(HPacket packet) { + this.legacyString = packet.readString(); + this.result = packet.readInteger(); + super.initialize(packet); + } + + @Override + public void appendToPacket(HPacket packet) { + packet.appendInt(IDENTIFIER | this.getFlags()); + packet.appendObjects( + this.legacyString, + this.result + ); + super.appendToPacket(packet); + } + + @Override + public String getLegacyString() { + return this.legacyString; + } + + @Override + public void setLegacyString(String legacyString) { + this.legacyString = legacyString == null ? "" : legacyString; + } + + public int getResult() { + return this.result; + } + + public void setResult(int result) { + this.result = result; + } +} diff --git a/G-Earth/src/main/java/gearth/protocol/memory/habboclient/macOs/MacOsHabboClient.java b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/macOs/MacOsHabboClient.java index 5cdcd0f..1c20100 100644 --- a/G-Earth/src/main/java/gearth/protocol/memory/habboclient/macOs/MacOsHabboClient.java +++ b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/macOs/MacOsHabboClient.java @@ -134,6 +134,10 @@ public class MacOsHabboClient extends HabboClient { private static byte[] hexStringToByteArray(String s) { int len = s.length(); + if (len % 2 == 1) { + s = "0" + s; + len += 1; + } byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)