mirror of
https://github.com/ProjectSWGCore/pswgcommon.git
synced 2026-01-15 23:04:19 -05:00
Fixed client crash issue with DraftSlotsQueryResponse when including multiple ingredients
This commit is contained in:
@@ -27,7 +27,6 @@
|
||||
package com.projectswg.common.data.schematic;
|
||||
|
||||
import com.projectswg.common.data.encodables.oob.StringId;
|
||||
import com.projectswg.common.data.schematic.IngridientSlot.IngridientType;
|
||||
import com.projectswg.common.encoding.Encodable;
|
||||
import com.projectswg.common.network.NetBuffer;
|
||||
|
||||
@@ -35,20 +34,20 @@ public class DraftSlotDataOption implements Encodable {
|
||||
|
||||
private StringId stfName;
|
||||
private String ingredientName;
|
||||
private IngridientType ingredientType;
|
||||
private SlotType slotType;
|
||||
private int amount;
|
||||
|
||||
public DraftSlotDataOption(StringId stfName, String ingredientName, IngridientType ingredientType, int amount) {
|
||||
public DraftSlotDataOption(StringId stfName, String ingredientName, SlotType slotType, int amount) {
|
||||
this.stfName = stfName;
|
||||
this.ingredientName = ingredientName;
|
||||
this.ingredientType = ingredientType;
|
||||
this.slotType = slotType;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public DraftSlotDataOption(){
|
||||
this.stfName = new StringId("", "");
|
||||
this.ingredientName = "";
|
||||
this.ingredientType = IngridientType.IT_NONE;
|
||||
this.slotType = SlotType.RESOURCES;
|
||||
this.amount = 0;
|
||||
}
|
||||
|
||||
@@ -60,8 +59,8 @@ public class DraftSlotDataOption implements Encodable {
|
||||
return ingredientName;
|
||||
}
|
||||
|
||||
public IngridientType getIngredientType() {
|
||||
return ingredientType;
|
||||
public SlotType getSlotType() {
|
||||
return slotType;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
@@ -72,7 +71,7 @@ public class DraftSlotDataOption implements Encodable {
|
||||
public void decode(NetBuffer data) {
|
||||
stfName = data.getEncodable(StringId.class);
|
||||
ingredientName = data.getUnicode();
|
||||
ingredientType = IngridientType.getTypeForInt(data.getByte());
|
||||
slotType = SlotType.IDENTICAL.getSlotType(data.getByte());
|
||||
amount = data.getInt();
|
||||
}
|
||||
|
||||
@@ -81,13 +80,22 @@ public class DraftSlotDataOption implements Encodable {
|
||||
NetBuffer data = NetBuffer.allocate(getLength());
|
||||
data.addEncodable(stfName);
|
||||
data.addUnicode(ingredientName);
|
||||
data.addByte(ingredientType.getId());
|
||||
data.addByte(slotType.getId());
|
||||
data.addInt(amount);
|
||||
if (slotType == SlotType.IDENTICAL) {
|
||||
data.addShort(0); // Client crash if we don't do this
|
||||
}
|
||||
return data.array();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 9 + stfName.getLength() + ingredientName.length() * 2;
|
||||
int length = 9 + stfName.getLength() + ingredientName.length() * 2;
|
||||
|
||||
if (slotType == SlotType.IDENTICAL) {
|
||||
length += 2;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,20 +41,17 @@ public class IngridientSlot implements Encodable{
|
||||
|
||||
private StringId name;
|
||||
private boolean optional;
|
||||
private String hardPoint;
|
||||
|
||||
|
||||
public IngridientSlot(StringId name, boolean optional) {
|
||||
this.name = name;
|
||||
this.optional = optional;
|
||||
this.slotOptions = new ArrayList<>();
|
||||
this.hardPoint = "";
|
||||
}
|
||||
|
||||
public IngridientSlot(){
|
||||
this.name = new StringId("", "");
|
||||
this.optional = false;
|
||||
this.slotOptions = new ArrayList<>();
|
||||
this.hardPoint = "";
|
||||
}
|
||||
|
||||
public StringId getName() {
|
||||
@@ -75,17 +72,12 @@ public class IngridientSlot implements Encodable{
|
||||
return Collections.unmodifiableList(slotOptions);
|
||||
}
|
||||
|
||||
public String getHardPoint() {
|
||||
return hardPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(NetBuffer data) {
|
||||
name = data.getEncodable(StringId.class);
|
||||
optional = data.getBoolean();
|
||||
slotOptions.clear();
|
||||
slotOptions.addAll(data.getList(DraftSlotDataOption.class));
|
||||
hardPoint = data.getAscii();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,7 +86,6 @@ public class IngridientSlot implements Encodable{
|
||||
data.addEncodable(name);
|
||||
data.addBoolean(optional);
|
||||
data.addList(slotOptions);
|
||||
data.addAscii(hardPoint);
|
||||
return data.array();
|
||||
}
|
||||
|
||||
@@ -104,32 +95,38 @@ public class IngridientSlot implements Encodable{
|
||||
for (DraftSlotDataOption draftSlotDataOption : slotOptions) {
|
||||
length += draftSlotDataOption.getLength();
|
||||
}
|
||||
return 7 + name.getLength() + hardPoint.length() + length;
|
||||
return 5 + name.getLength() + length;
|
||||
}
|
||||
|
||||
public enum IngridientType {
|
||||
UNDEFINED (Integer.MIN_VALUE),
|
||||
IT_NONE (0),
|
||||
IT_ITEM (1),
|
||||
IT_TEMPLATE (2),
|
||||
IT_RESOURCE_TYPE (3),
|
||||
IT_RESOURCE_CLASS (4),
|
||||
IT_TEMPLATE_GENERIC (5),
|
||||
IT_SCHEMATIC (6),
|
||||
IT_SCHEMATIC_GENERIC (7);
|
||||
UNDEFINED (Integer.MIN_VALUE, SlotType.RESOURCES),
|
||||
IT_NONE (0, SlotType.RESOURCES),
|
||||
IT_ITEM (1, SlotType.SIMILAR_COMPONENTS),
|
||||
IT_TEMPLATE (2, SlotType.IDENTICAL),
|
||||
IT_RESOURCE_TYPE (3, SlotType.RESOURCES),
|
||||
IT_RESOURCE_CLASS (4, SlotType.RESOURCES),
|
||||
IT_TEMPLATE_GENERIC (5, SlotType.IDENTICAL),
|
||||
IT_SCHEMATIC (6, SlotType.SIMILAR_COMPONENTS),
|
||||
IT_SCHEMATIC_GENERIC (7, SlotType.SIMILAR_COMPONENTS);
|
||||
|
||||
private static final EnumLookup<Integer, IngridientType> LOOKUP = new EnumLookup<>(IngridientType.class, i -> i.getId());
|
||||
|
||||
private int id;
|
||||
private final int id;
|
||||
private final SlotType slotType;
|
||||
|
||||
IngridientType(int id) {
|
||||
IngridientType(int id, SlotType slotType) {
|
||||
this.id = id;
|
||||
this.slotType = slotType;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public SlotType getSlotType() {
|
||||
return slotType;
|
||||
}
|
||||
|
||||
public static IngridientType getTypeForInt(int id) {
|
||||
return LOOKUP.getEnum(id, UNDEFINED);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2023 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of PSWGCommon. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* PSWGCommon is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* PSWGCommon is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with PSWGCommon. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.data.schematic
|
||||
|
||||
enum class SlotType(val id: Int) {
|
||||
IDENTICAL(2), RESOURCES(4), SIMILAR_COMPONENTS(5);
|
||||
|
||||
private val map = mutableMapOf<Int, SlotType>()
|
||||
|
||||
fun getSlotType(id: Int): SlotType {
|
||||
if (map.isEmpty()) {
|
||||
for (type in values()) {
|
||||
map[type.id] = type
|
||||
}
|
||||
}
|
||||
|
||||
return map.getOrElse(id) { RESOURCES }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,12 +33,16 @@ import com.projectswg.common.network.NetBuffer;
|
||||
public class DraftSlotsQueryResponse extends ObjectController {
|
||||
|
||||
private final static int CRC = 0x01BF;
|
||||
|
||||
|
||||
private DraftSchematic schematic;
|
||||
|
||||
public DraftSlotsQueryResponse(DraftSchematic schematic, long objectId) {
|
||||
private int clientCrc;
|
||||
private int serverCrc;
|
||||
|
||||
public DraftSlotsQueryResponse(DraftSchematic schematic, long objectId, int clientCrc, int serverCrc) {
|
||||
super(objectId, CRC);
|
||||
this.schematic = schematic;
|
||||
this.clientCrc = clientCrc;
|
||||
this.serverCrc = serverCrc;
|
||||
}
|
||||
|
||||
public DraftSlotsQueryResponse(NetBuffer data){
|
||||
@@ -49,7 +53,8 @@ public class DraftSlotsQueryResponse extends ObjectController {
|
||||
@Override
|
||||
public void decode(NetBuffer data) {
|
||||
decodeHeader(data);
|
||||
schematic.setCombinedCrc(data.getLong());
|
||||
clientCrc = data.getInt();
|
||||
serverCrc = data.getInt();
|
||||
schematic.setComplexity(data.getInt());
|
||||
schematic.setVolume(data.getInt());
|
||||
schematic.setCanManufacture(data.getBoolean());
|
||||
@@ -65,11 +70,12 @@ public class DraftSlotsQueryResponse extends ObjectController {
|
||||
}
|
||||
NetBuffer data = NetBuffer.allocate(HEADER_LENGTH + 21 + length);
|
||||
encodeHeader(data);
|
||||
data.addLong(schematic.getCombinedCrc());
|
||||
data.addInt(clientCrc);
|
||||
data.addInt(serverCrc);
|
||||
data.addInt(schematic.getComplexity());
|
||||
data.addInt(schematic.getVolume());
|
||||
data.addBoolean(schematic.isCanManufacture());
|
||||
data.addList(schematic.getIngridientSlot());
|
||||
data.addList(schematic.getIngridientSlot());
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user