diff --git a/src/resources/common/Opcodes.java b/src/resources/common/Opcodes.java index a84429ad..1991054c 100644 --- a/src/resources/common/Opcodes.java +++ b/src/resources/common/Opcodes.java @@ -43,5 +43,6 @@ public class Opcodes { public static int RequestGalaxyLoopTimes = 0x7D842D68; public static int SelectCharacter = 0xB5098D76; public static int SuiEventNotification = 0x092D3564; + public static int DeltasMessage = 0x12862153; } diff --git a/src/resources/common/StringUtilities.java b/src/resources/common/StringUtilities.java new file mode 100644 index 00000000..a613f4df --- /dev/null +++ b/src/resources/common/StringUtilities.java @@ -0,0 +1,71 @@ +package resources.common; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +public class StringUtilities { + + public static String getAsciiString(ByteBuffer buffer) { + return getString(buffer, "US-ASCII"); + } + + public static String getUnicodeString(ByteBuffer buffer) { + return getString(buffer, "UTF-16LE"); + } + + public static byte[] getAsciiString(String string) { + return getString(string, "US-ASCII"); + } + + public static byte[] getUnicodeString(String string) { + return getString(string, "UTF-16LE"); + } + + private static String getString(ByteBuffer buffer, String charFormat) { + String result; + int length; + + if (charFormat == "UTF-16LE") { + length = buffer.order(ByteOrder.LITTLE_ENDIAN).getInt(); + } else { + length = buffer.order(ByteOrder.LITTLE_ENDIAN).getShort(); + } + + int bufferPosition = buffer.position(); + + try { + result = new String(buffer.array(), bufferPosition, length, charFormat); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return ""; + } + + buffer.position(bufferPosition + length); + + return result; + } + + private static byte[] getString(String string, String charFormat) { + ByteBuffer result; + int length = 2 + string.length(); + + if (charFormat == "UTF-16LE") { + result = ByteBuffer.allocate(length * 2).order(ByteOrder.LITTLE_ENDIAN); + result.putInt(string.length()); + } else { + result = ByteBuffer.allocate(length).order(ByteOrder.LITTLE_ENDIAN); + result.putShort((short)string.length()); + } + + try { + result.put(string.getBytes(charFormat)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return new byte[] { }; + } + + return result.array(); + } + +} diff --git a/src/resources/objects/GCWZone.java b/src/resources/objects/CurrentServerGCWZoneHistory.java similarity index 63% rename from src/resources/objects/GCWZone.java rename to src/resources/objects/CurrentServerGCWZoneHistory.java index 35db8508..3e652481 100644 --- a/src/resources/objects/GCWZone.java +++ b/src/resources/objects/CurrentServerGCWZoneHistory.java @@ -21,73 +21,71 @@ ******************************************************************************/ package resources.objects; -public class GCWZone implements ListObject { +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +public class CurrentServerGCWZoneHistory extends ListObject { private byte unknown1 = 0; - private String server = "current"; private String zone = ""; private int lastUpdateTime = ((int) System.currentTimeMillis()); private int percent = 50; - private int gcwPoints = 0; - - public GCWZone(String server, String zone) { - this.server = server; + + public CurrentServerGCWZoneHistory(String zone, int percent) { this.zone = zone; + this.percent = percent; } - public GCWZone(String zone) { + public CurrentServerGCWZoneHistory(String zone) { this.zone = zone; } - public GCWZone() { - - } - public byte getUnknown1() { - return unknown1; + synchronized(objectMutex) { + return unknown1; + } } public void setUnknown1(byte unknown1) { - this.unknown1 = unknown1; - } - - public String getServer() { - return server; + synchronized(objectMutex) { + this.unknown1 = unknown1; + } } public String getZone() { - return zone; + synchronized(objectMutex) { + return zone; + } } public int getLastUpdateTime() { - return lastUpdateTime; + synchronized(objectMutex) { + return lastUpdateTime; + } } public int getPercent() { - return percent; + synchronized(objectMutex) { + return percent; + } } public void setPercent(int percent) { - this.percent = percent; - this.lastUpdateTime = ((int) System.currentTimeMillis()); + synchronized(objectMutex) { + this.percent = percent; + this.lastUpdateTime = ((int) System.currentTimeMillis()); + } } - public int getGCWPoints() { - return gcwPoints; - } - - public void addGCWPoints(int gcwPoints) { - this.gcwPoints += gcwPoints; - } - - public void removeGCWPoints(int gcwPoints) { - this.gcwPoints = (((this.gcwPoints - gcwPoints) < 0) ? 0 : this.gcwPoints - gcwPoints); - } - - @Override public byte[] getBytes() { - // TODO Auto-generated method stub - return null; + synchronized(objectMutex) { + IoBuffer buffer = bufferPool.allocate((8 + zone.length() + 2), false).order(ByteOrder.LITTLE_ENDIAN); + buffer.put(getAsciiString(zone)); + buffer.putInt(lastUpdateTime); + buffer.putInt(percent); + return buffer.array(); + } } } diff --git a/src/resources/objects/CurrentServerGCWZonePercent.java b/src/resources/objects/CurrentServerGCWZonePercent.java new file mode 100644 index 00000000..96402caa --- /dev/null +++ b/src/resources/objects/CurrentServerGCWZonePercent.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.objects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +public class CurrentServerGCWZonePercent extends ListObject { + + private byte unknown1 = 0; + private String zone = ""; + private int percent = 60; + private int gcwPoints = 0; + + public CurrentServerGCWZonePercent(String zone) { + this.zone = zone; + } + + public byte getUnknown1() { + synchronized(objectMutex) { + return unknown1; + } + } + + public void setUnknown1(byte unknown1) { + synchronized(objectMutex) { + this.unknown1 = unknown1; + } + } + + public String getZone() { + synchronized(objectMutex) { + return zone; + } + } + + public int getPercent() { + synchronized(objectMutex) { + return percent; + } + } + + public void setPercent(int percent, SWGList historyList) { + synchronized(objectMutex) { + int historyCount = 0; + int firstHistoryIndex = historyList.get().size(); + int lastHistoryIndex = historyList.get().size(); + + for (int i = 0; i < historyList.size(); i++) { + if (historyList.get(i).getZone() == getZone()) { + historyCount++; + lastHistoryIndex = i; + + if (historyCount == 1) { + firstHistoryIndex = i; + } + } + } + + if (historyCount > 10) { + historyList.remove(firstHistoryIndex); + } + + historyList.add(lastHistoryIndex, new CurrentServerGCWZoneHistory(zone, percent)); + + this.percent = percent; + } + } + + public int getGCWPoints() { + synchronized(objectMutex) { + return gcwPoints; + } + } + + public void addGCWPoints(int gcwPoints) { + synchronized(objectMutex) { + this.gcwPoints += gcwPoints; + } + } + + public void removeGCWPoints(int gcwPoints) { + synchronized(objectMutex) { + this.gcwPoints = (((this.gcwPoints - gcwPoints) < 0) ? 0 : this.gcwPoints - gcwPoints); + } + } + + public byte[] getBytes() { + synchronized(objectMutex) { + IoBuffer buffer = bufferPool.allocate((4 + zone.length() + 2), false).order(ByteOrder.LITTLE_ENDIAN); + buffer.put(getAsciiString(zone)); + buffer.putInt(percent); + return buffer.array(); + } + } + +} diff --git a/src/resources/objects/IListObject.java b/src/resources/objects/IListObject.java new file mode 100644 index 00000000..0af809cf --- /dev/null +++ b/src/resources/objects/IListObject.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.objects; + +public interface IListObject { + + public byte[] getBytes(); + +} diff --git a/src/resources/objects/ListObject.java b/src/resources/objects/ListObject.java index 2d4cd295..e643d075 100644 --- a/src/resources/objects/ListObject.java +++ b/src/resources/objects/ListObject.java @@ -1,7 +1,30 @@ package resources.objects; -public interface ListObject { +import java.nio.ByteBuffer; + +import org.apache.mina.core.buffer.SimpleBufferAllocator; + +import resources.common.StringUtilities; + +public abstract class ListObject implements IListObject { - public byte[] getBytes(); + protected final Object objectMutex = new Object(); + public SimpleBufferAllocator bufferPool = new SimpleBufferAllocator(); + protected String getAsciiString(ByteBuffer buffer) { + return StringUtilities.getAsciiString(buffer); + } + + protected String getUnicodeString(ByteBuffer buffer) { + return StringUtilities.getUnicodeString(buffer); + } + + protected byte[] getAsciiString(String string) { + return StringUtilities.getAsciiString(string); + } + + protected byte[] getUnicodeString(String string) { + return StringUtilities.getUnicodeString(string); + } + } diff --git a/src/resources/objects/ObjectMessageBuilder.java b/src/resources/objects/ObjectMessageBuilder.java index 53b4ab66..8a0ebbbd 100644 --- a/src/resources/objects/ObjectMessageBuilder.java +++ b/src/resources/objects/ObjectMessageBuilder.java @@ -28,6 +28,8 @@ import java.nio.ByteOrder; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.buffer.SimpleBufferAllocator; +import resources.common.Opcodes; + import engine.resources.objects.SWGObject; public abstract class ObjectMessageBuilder { @@ -36,50 +38,78 @@ public abstract class ObjectMessageBuilder { public SimpleBufferAllocator bufferPool = new SimpleBufferAllocator(); public IoBuffer createBaseline(String objectType, byte viewType, IoBuffer data, int size) { + IoBuffer buffer = bufferPool.allocate(23 + size, false).order(ByteOrder.LITTLE_ENDIAN); - IoBuffer buf = bufferPool.allocate(23 + size, false).order(ByteOrder.LITTLE_ENDIAN); - buf.putShort((short) 5); - buf.putInt(0x68A75F0C); - buf.putLong(object.getObjectID()); + buffer.putShort((short) 5); + buffer.putInt(0x68A75F0C); + buffer.putLong(object.getObjectID()); try { - buf.put(reverse(objectType).getBytes("US-ASCII")); + buffer.put(reverse(objectType).getBytes("US-ASCII")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } - buf.put(viewType); - buf.putInt(size); // size - buf.put(data); - buf.flip(); - return buf; + buffer.put(viewType); + buffer.putInt(size); + buffer.put(data); + buffer.flip(); + + return buffer; } public IoBuffer createDelta(String objectType, byte viewType, short updateCount, short updateType, IoBuffer data, int size) { + IoBuffer buffer = bufferPool.allocate(27 + size, false).order(ByteOrder.LITTLE_ENDIAN); - IoBuffer buf = bufferPool.allocate(27 + size, false).order(ByteOrder.LITTLE_ENDIAN); - buf.putShort((short) 5); - buf.putInt(0x12862153); - buf.putLong(object.getObjectID()); + buffer.putShort((short) 5); + buffer.putInt(Opcodes.DeltasMessage); + buffer.putLong(object.getObjectID()); try { - buf.put(reverse(objectType).getBytes("US-ASCII")); + buffer.put(reverse(objectType).getBytes("US-ASCII")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } - buf.put(viewType); - buf.putInt(size); // size - buf.putShort(updateCount); - buf.putShort(updateType); - buf.put(data); - - buf.flip(); - return buf; - + buffer.put(viewType); + buffer.putInt(size); + buffer.putShort(updateCount); + buffer.putShort(updateType); + buffer.put(data); + buffer.flip(); + return buffer; + } + + public IoBuffer createDelta(String objectType, byte viewType, short updateCount, IoBuffer data, int size) { + IoBuffer buffer = bufferPool.allocate(25 + size, false).order(ByteOrder.LITTLE_ENDIAN); + + buffer.putShort((short) 5); + buffer.putInt(Opcodes.DeltasMessage); + buffer.putLong(object.getObjectID()); + try { + buffer.put(reverse(objectType).getBytes("US-ASCII")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + buffer.put(viewType); + buffer.putInt(size); + buffer.putShort(updateCount); + buffer.put(data); + buffer.flip(); + + return buffer; + } + + public IoBuffer createDeltaObject(short updateType, IoBuffer data, int size) { + IoBuffer buffer = bufferPool.allocate(2 + size, false).order(ByteOrder.LITTLE_ENDIAN); + + buffer.putShort(updateType); + buffer.put(data.array()); + + return buffer; } public SWGObject getObject() { return object; } public void setObject(SWGObject object) { this.object = object; } - public abstract void sendListDelta(short updateType, IoBuffer buffer); + public abstract void sendListDelta(byte viewType, short updateType, IoBuffer buffer); public abstract void sendBaselines(); diff --git a/src/resources/objects/OtherServerGCWZonePercent.java b/src/resources/objects/OtherServerGCWZonePercent.java new file mode 100644 index 00000000..677ec790 --- /dev/null +++ b/src/resources/objects/OtherServerGCWZonePercent.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.objects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +public class OtherServerGCWZonePercent extends ListObject { + + private byte unknown1 = 0; + private String server = "SWG"; + private String zone = ""; + private int lastUpdateTime = ((int) System.currentTimeMillis()); + private int percent = 50; + private int gcwPoints = 0; + + public OtherServerGCWZonePercent(String server, String zone) { + this.server = server; + this.zone = zone; + } + + public OtherServerGCWZonePercent(String zone) { + this.zone = zone; + } + + public OtherServerGCWZonePercent() { + + } + + public byte getUnknown1() { + synchronized(objectMutex) { + return unknown1; + } + } + + public void setUnknown1(byte unknown1) { + synchronized(objectMutex) { + this.unknown1 = unknown1; + } + } + + public String getServer() { + synchronized(objectMutex) { + return server; + } + } + + public String getZone() { + synchronized(objectMutex) { + return zone; + } + } + + public int getLastUpdateTime() { + synchronized(objectMutex) { + return lastUpdateTime; + } + } + + public int getPercent() { + synchronized(objectMutex) { + return percent; + } + } + + public void setPercent(int percent) { + synchronized(objectMutex) { + this.percent = percent; + this.lastUpdateTime = ((int) System.currentTimeMillis()); + } + } + + public int getGCWPoints() { + synchronized(objectMutex) { + return gcwPoints; + } + } + + public void addGCWPoints(int gcwPoints) { + synchronized(objectMutex) { + this.gcwPoints += gcwPoints; + } + } + + public void removeGCWPoints(int gcwPoints) { + synchronized(objectMutex) { + this.gcwPoints = (((this.gcwPoints - gcwPoints) < 0) ? 0 : this.gcwPoints - gcwPoints); + } + } + + public byte[] getBytes() { + synchronized(objectMutex) { + IoBuffer buffer = bufferPool.allocate((4 + server.length() + zone.length() + 4), false).order(ByteOrder.LITTLE_ENDIAN); + buffer.put(getAsciiString(server)); + buffer.put(getAsciiString(zone)); + buffer.putInt(percent); + return buffer.array(); + } + } + +} diff --git a/src/resources/objects/SWGList.java b/src/resources/objects/SWGList.java index 329192ea..f33d38be 100644 --- a/src/resources/objects/SWGList.java +++ b/src/resources/objects/SWGList.java @@ -1,146 +1,294 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ package resources.objects; import java.nio.ByteOrder; import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import org.apache.mina.core.buffer.IoBuffer; import com.sleepycat.persist.model.NotPersistent; -public class SWGList { +/* A SWGList element MUST implement IListObject, or it will refuse to work with it */ + +public class SWGList implements List { - private List list = new ArrayList(); + private List list = new ArrayList(); @NotPersistent private int updateCounter; private ObjectMessageBuilder messageBuilder; + private byte viewType; private short updateType; protected final Object objectMutex = new Object(); - public SWGList(ObjectMessageBuilder messageBuilder, short updateType) { + public SWGList(ObjectMessageBuilder messageBuilder, int viewType, int updateType) { this.messageBuilder = messageBuilder; - this.updateType = updateType; + this.viewType = (byte) viewType; + this.updateType = (short) updateType; } - public void add(ListObject e) { + public boolean add(E e) { synchronized(objectMutex) { - byte[] bytes = e.getBytes(); - list.add(e); - updateCounter++; - - IoBuffer buffer = messageBuilder.bufferPool.allocate((bytes.length + 11), false).order(ByteOrder.LITTLE_ENDIAN);; - buffer.putInt(1); - buffer.putInt(updateCounter); - buffer.put((byte) 1); - buffer.putShort((short) list.lastIndexOf(e)); - buffer.put(bytes); - messageBuilder.sendListDelta(updateType, buffer); - } - } - - public ListObject get(int index) { - synchronized(objectMutex) { - return list.get(index); - } - } - - public void set(int index, ListObject element) { - synchronized(objectMutex) { - byte[] bytes = element.getBytes(); - list.set(index, element); - updateCounter++; - - IoBuffer buffer = messageBuilder.bufferPool.allocate((bytes.length + 11), false).order(ByteOrder.LITTLE_ENDIAN);; - buffer.putInt(1); - buffer.putInt(updateCounter); - buffer.put((byte) 2); - buffer.putShort((short) index); - buffer.put(bytes); - messageBuilder.sendListDelta(updateType, buffer); - } - } - - public List get() { - synchronized(objectMutex) { - return list; - } - } - - public void set(List list) { - synchronized(objectMutex) { - this.list = list; - updateCounter++; - - IoBuffer buffer = messageBuilder.bufferPool.allocate(11, false).order(ByteOrder.LITTLE_ENDIAN); - buffer.putInt(list.size()); - buffer.putInt(updateCounter); - buffer.put((byte) 3); - buffer.putShort((short) list.size()); - - for (ListObject object : list) { - buffer = messageBuilder.bufferPool.allocate(buffer.position(), false).put(buffer.array(), 0, buffer.position()); - buffer.put(object.getBytes()); + if (e instanceof IListObject) { + if (list.add(e)) { + queue(item(1, list.lastIndexOf(e), ((IListObject) e).getBytes(), true, true)); + + return true; + } } - messageBuilder.sendListDelta(updateType, buffer); + return false; } } - public boolean contains(ListObject o) { + public void add(int index, E element) { synchronized(objectMutex) { - return list.contains(o); + if (element instanceof IListObject) { + list.add(index, element); + queue(item(1, index, ((IListObject) element).getBytes(), true, true)); + } } } - public void remove(int index) { + public boolean addAll(Collection c) { synchronized(objectMutex) { - list.remove(index); - updateCounter++; + if (!c.isEmpty()) { + List buffer = new ArrayList(); + boolean success = false; + + for (E element : c) { + if (element instanceof IListObject) { + if (list.add(element)) { + buffer.add(item(1, list.lastIndexOf(element), ((IListObject) element).getBytes(), true, true)); + success = true; + } + } else { + return false; + } + } + + if (success == true) { + queue(buffer); + } else { + return false; + } + } - IoBuffer buffer = messageBuilder.bufferPool.allocate(11, false).order(ByteOrder.LITTLE_ENDIAN);; - buffer.putInt(1); - buffer.putInt(updateCounter); - buffer.put((byte) 0); - buffer.putShort((short) index); - messageBuilder.sendListDelta(updateType, buffer); + return false; } } - public void remove(ListObject o) { + public boolean addAll(int index, Collection c) { synchronized(objectMutex) { - int index = list.indexOf(o); + if (!c.isEmpty()) { + List buffer = new ArrayList(); + + for (E element : c) { + if (element instanceof IListObject) { + list.add(index, element); + buffer.add(item(1, index, ((IListObject) element).getBytes(), true, true)); + index++; + } else { + return false; + } + } + + queue(buffer); + + return true; + } - list.remove(index); - updateCounter++; - - IoBuffer buffer = messageBuilder.bufferPool.allocate(11, false).order(ByteOrder.LITTLE_ENDIAN);; - buffer.putInt(1); - buffer.putInt(updateCounter); - buffer.put((byte) 0); - buffer.putShort((short) index); - messageBuilder.sendListDelta(updateType, buffer); + return false; } - } public void clear() { synchronized(objectMutex) { list.clear(); - updateCounter++; - - IoBuffer buffer = messageBuilder.bufferPool.allocate(9, false).order(ByteOrder.LITTLE_ENDIAN);; - buffer.putInt(0); - buffer.putInt(updateCounter); - buffer.put((byte) 0); - messageBuilder.sendListDelta(updateType, buffer); + queue(item(4, 0, null, false, false)); } } - public int getUpdateCounter() { + public boolean contains(Object o) { synchronized(objectMutex) { - return updateCounter; + return list.contains(o); + } + } + + public boolean containsAll(Collection c) { + synchronized(objectMutex) { + return list.containsAll(c); + } + } + + public E get(int index) { + synchronized(objectMutex) { + return list.get(index); + } + } + + public List get() { + synchronized(objectMutex) { + return list; + } + } + + public int indexOf(Object o) { + synchronized(objectMutex) { + return list.indexOf(o); + } + } + + public boolean isEmpty() { + synchronized(objectMutex) { + return list.isEmpty(); + } + } + + public Iterator iterator() { + synchronized(objectMutex) { + return list.iterator(); + } + } + + public int lastIndexOf(Object o) { + synchronized(objectMutex) { + return list.lastIndexOf(o); + } + } + + public ListIterator listIterator() { + synchronized(objectMutex) { + return list.listIterator(); + } + } + + public ListIterator listIterator(int index) { + synchronized(objectMutex) { + return listIterator(index); + } + } + + public boolean remove(Object o) { + synchronized(objectMutex) { + int index = list.indexOf(o); + + if (list.remove(o)) { + queue(item(1, index, null, true, false)); + return true; + } else { + return false; + } + } + } + + public E remove(int index) { + synchronized(objectMutex) { + E element = list.remove(index); + + queue(item(1, index, null, true, false)); + + return (E) element; + } + } + + public boolean removeAll(Collection c) { + synchronized(objectMutex) { + if (!c.isEmpty()) { + List buffer = new ArrayList(); + int index; + boolean success = false; + + for (Object element : c) { + index = list.indexOf(element); + + if (list.remove(element)) { + buffer.add(item(0, index, null, true, false)); + success = true; + } + } + + if (success) { + queue(buffer); + } + + return success; + } + + return false; + } + } + + public boolean retainAll(Collection c) { + synchronized(objectMutex) { + return list.retainAll(c); + } + } + + public E set(int index, E element) { + synchronized(objectMutex) { + if (element instanceof IListObject) { + E previousElement = list.set(index, element); + + queue(item(2, index, ((IListObject) element).getBytes(), true, true)); + + return previousElement; + } + + return null; + } + } + + public boolean set(List list) { + synchronized(objectMutex) { + byte[] newListData = { 0x03 }; + + if (!list.isEmpty()) { + for (E element : list) { + if (element instanceof IListObject) { + IoBuffer buffer = messageBuilder.bufferPool.allocate((newListData.length + ((IListObject) element).getBytes().length), false).order(ByteOrder.LITTLE_ENDIAN); + buffer.put(newListData); + buffer.put(((IListObject) element).getBytes()); + newListData = buffer.array(); + } else { + return false; + } + } + + this.list = list; + + updateCounter++; + queue(newListData); + + return true; + } + + return false; } } @@ -149,5 +297,63 @@ public class SWGList { return list.size(); } } + + public List subList(int fromIndex, int toIndex) { + synchronized(objectMutex) { + return list.subList(fromIndex, toIndex); + } + } + + public Object[] toArray() { + synchronized(objectMutex) { + return list.toArray(); + } + } + + public T[] toArray(T[] a) { + synchronized(objectMutex) { + return list.toArray(a); + } + } + + public int getUpdateCounter() { + return updateCounter; + } + + private byte[] item(int type, int index, byte[] data, boolean useIndex, boolean useData) { + int size = 1 + ((useIndex) ? 2 : 0) + ((useData) ? data.length : 0); + + IoBuffer buffer = messageBuilder.bufferPool.allocate((size), false).order(ByteOrder.LITTLE_ENDIAN); + buffer.put((byte) type); + if (useIndex) buffer.putShort((short) index); + if (useData) buffer.put(data); + + updateCounter++; + + return buffer.array(); + } + + private void queue(byte[] data) { + IoBuffer buffer = messageBuilder.bufferPool.allocate((data.length + 8), false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(1); + buffer.putInt(updateCounter); + buffer.put(data); + messageBuilder.sendListDelta(viewType, updateType, buffer); + } + + private void queue(List data) { + int size = 0; + + for (byte[] queued : data) { + size += queued.length; + } + + IoBuffer buffer = messageBuilder.bufferPool.allocate((size + 8), false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(data.size()); + buffer.putInt(updateCounter); + for (byte[] queued : data) buffer.put(queued); + + messageBuilder.sendListDelta(viewType, updateType, buffer); + } } diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 4d92919a..86c38910 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -595,7 +595,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { } @Override - public void sendListDelta(short updateType, IoBuffer buffer) { + public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) { // TODO Auto-generated method stub } diff --git a/src/resources/objects/guild/GuildMessageBuilder.java b/src/resources/objects/guild/GuildMessageBuilder.java index fb10d893..1aabcb20 100644 --- a/src/resources/objects/guild/GuildMessageBuilder.java +++ b/src/resources/objects/guild/GuildMessageBuilder.java @@ -22,15 +22,21 @@ package resources.objects.guild; import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.List; import org.apache.mina.core.buffer.IoBuffer; -import resources.objects.GCWZone; +import resources.objects.CurrentServerGCWZoneHistory; +import resources.objects.CurrentServerGCWZonePercent; import resources.objects.Guild; import resources.objects.ObjectMessageBuilder; +import resources.objects.OtherServerGCWZonePercent; public class GuildMessageBuilder extends ObjectMessageBuilder { - + + private List zoneUpdates = new ArrayList(); + public GuildMessageBuilder(GuildObject guildObject) { setObject(guildObject); } @@ -47,8 +53,8 @@ public class GuildMessageBuilder extends ObjectMessageBuilder { buffer.put(getUnicodeString(guilds.getCustomName())); buffer.putInt(guilds.getVolume()); buffer.putInt(guilds.getGuildList().size()); - buffer.putInt(guilds.getGuildListUpdateCounter()); - for (Guild object : guilds.getGuildList()) { + buffer.putInt(guilds.getGuildList().getUpdateCounter()); + for (Guild object : guilds.getGuildList().get()) { buffer.put(getAsciiString(object.getString())); } @@ -78,52 +84,52 @@ public class GuildMessageBuilder extends ObjectMessageBuilder { buffer.putInt(guilds.getUnknown1()); buffer.putShort(guilds.getUnknown2()); buffer.putInt(guilds.getCurrentServerGCWZonePercentList().size()); - buffer.putInt(guilds.getCurrentServerGCWZonePercentListUpdateCounter()); - for (GCWZone object : guilds.getCurrentServerGCWZonePercentList()) { + buffer.putInt(guilds.getCurrentServerGCWZonePercentList().getUpdateCounter()); + for (CurrentServerGCWZonePercent object : guilds.getCurrentServerGCWZonePercentList().get()) { buffer.put(object.getUnknown1()); buffer.put(getAsciiString(object.getZone())); buffer.putInt(object.getPercent()); } buffer.putInt(guilds.getCurrentServerGCWTotalPercentList().size()); - buffer.putInt(guilds.getCurrentServerGCWTotalPercentListUpdateCounter()); - for (GCWZone object : guilds.getCurrentServerGCWTotalPercentList()) { + buffer.putInt(guilds.getCurrentServerGCWTotalPercentList().getUpdateCounter()); + for (CurrentServerGCWZonePercent object : guilds.getCurrentServerGCWTotalPercentList().get()) { buffer.put(object.getUnknown1()); buffer.put(getAsciiString(object.getZone())); buffer.putInt(object.getPercent()); } buffer.putInt(guilds.getCurrentServerGCWZoneHistoryList().size()); - buffer.putInt(guilds.getCurrentServerGCWZoneHistoryListUpdateCounter()); - for (GCWZone object : guilds.getCurrentServerGCWZoneHistoryList()) { + buffer.putInt(guilds.getCurrentServerGCWZoneHistoryList().getUpdateCounter()); + for (CurrentServerGCWZoneHistory object : guilds.getCurrentServerGCWZoneHistoryList().get()) { buffer.put(object.getUnknown1()); buffer.put(getAsciiString(object.getZone())); buffer.putInt(object.getLastUpdateTime()); buffer.putInt(object.getPercent()); } buffer.putInt(guilds.getCurrentServerGCWTotalHistoryList().size()); - buffer.putInt(guilds.getCurrentServerGCWTotalHistoryListUpdateCounter()); - for (GCWZone object : guilds.getCurrentServerGCWTotalHistoryList()) { + buffer.putInt(guilds.getCurrentServerGCWTotalHistoryList().getUpdateCounter()); + for (CurrentServerGCWZoneHistory object : guilds.getCurrentServerGCWTotalHistoryList().get()) { buffer.put(object.getUnknown1()); buffer.put(getAsciiString(object.getZone())); buffer.putInt(object.getLastUpdateTime()); buffer.putInt(object.getPercent()); } buffer.putInt(guilds.getOtherServerGCWZonePercentList().size()); - buffer.putInt(guilds.getOtherServerGCWZonePercentListUpdateCounter()); - for (GCWZone object : guilds.getOtherServerGCWZonePercentList()) { + buffer.putInt(guilds.getOtherServerGCWZonePercentList().getUpdateCounter()); + for (OtherServerGCWZonePercent object : guilds.getOtherServerGCWZonePercentList().get()) { buffer.put(object.getUnknown1()); buffer.put(getAsciiString(object.getServer())); buffer.put(getAsciiString(object.getZone())); buffer.putInt(object.getPercent()); } buffer.putInt(guilds.getOtherServerGCWTotalPercentList().size()); - buffer.putInt(guilds.getOtherServerGCWTotalPercentListUpdateCounter()); - for (GCWZone object : guilds.getOtherServerGCWTotalPercentList()) { + buffer.putInt(guilds.getOtherServerGCWTotalPercentList().getUpdateCounter()); + for (OtherServerGCWZonePercent object : guilds.getOtherServerGCWTotalPercentList().get()) { buffer.put(object.getUnknown1()); buffer.put(getAsciiString(object.getServer())); buffer.put(getAsciiString(object.getZone())); buffer.putInt(object.getPercent()); } - buffer.putInt(5); // Unknown + buffer.putInt(guilds.getUnknown3()); int size = buffer.position(); buffer = bufferPool.allocate(size, false).put(buffer.array(), 0, size); @@ -133,14 +139,170 @@ public class GuildMessageBuilder extends ObjectMessageBuilder { return buffer; } - @Override - public void sendListDelta(short updateType, IoBuffer buffer) { - switch (updateType) { - default: - return; + public IoBuffer buildComplexity(float complexity) { + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + + buffer.putFloat(complexity); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("GILD", (byte) 3, (short) 1, (short) 0, buffer, size + 4); + + return buffer; + } + + public IoBuffer buildSTF(String STFFile, int STFSpacer, String STFName) { + IoBuffer buffer = bufferPool.allocate((STFFile.length() + STFName.length() + 8), false).order(ByteOrder.LITTLE_ENDIAN); + + buffer.put(getAsciiString(STFFile)); + buffer.putInt(STFSpacer); + buffer.put(getAsciiString(STFName)); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("GILD", (byte) 3, (short) 1, (short) 1, buffer, size + 4); + + return buffer; + } + + public IoBuffer buildCustomName(String customName) { + IoBuffer buffer = bufferPool.allocate((customName.length() + 4), false).order(ByteOrder.LITTLE_ENDIAN); + + buffer.put(getUnicodeString(customName)); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("GILD", (byte) 3, (short) 1, (short) 2, buffer, size + 4); + + return buffer; + } + + public IoBuffer buildVolume(int volume) { + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + + buffer.putInt(volume); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("GILD", (byte) 3, (short) 1, (short) 3, buffer, size + 4); + + return buffer; + } + + public IoBuffer buildServerId(int serverId) { + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + + buffer.putInt(serverId); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("GILD", (byte) 6, (short) 1, (short) 0, buffer, size + 4); + + return buffer; + } + + public IoBuffer buildUnknowns(int unknown1, short unknown2) { + IoBuffer buffer = bufferPool.allocate(6, false).order(ByteOrder.LITTLE_ENDIAN); + + buffer.putInt(unknown1); + buffer.putShort(unknown2); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("GILD", (byte) 6, (short) 1, (short) 1, buffer, size + 4); + + return buffer; + } + + public IoBuffer buildGCWDelta() { + synchronized(zoneUpdates) { + if (zoneUpdates.size() > 0) { + int updates = zoneUpdates.size(); + int size = 4; + + for (int i = 0; i < zoneUpdates.size(); i++) { + size += zoneUpdates.get(i).position(); + } + + IoBuffer buffer = bufferPool.allocate(size, false).order(ByteOrder.LITTLE_ENDIAN); + + for (int i = 0; i < zoneUpdates.size(); i++) { + buffer.put(zoneUpdates.get(i).array()); + } + + zoneUpdates.clear(); + + buffer.flip(); + + return createDelta("GILD", (byte) 6, (short) updates, buffer, size); + } else { + return null; + } } } + public IoBuffer buildUnknown3(int unknown3) { + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + + buffer.putInt(unknown3); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("GILD", (byte) 6, (short) 1, (short) 8, buffer, size + 4); + + return buffer; + } + + final protected static char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + int v; + for ( int j = 0; j < bytes.length; j++ ) { + v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } + + @Override + public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) { + synchronized(zoneUpdates) { + switch (viewType) { + case 3: + { + switch (updateType) { + case 4: + { + buffer.flip(); + buffer = createDelta("GILD", (byte) 3, (short) 1, (short) 4, buffer, buffer.position() + 4); + + for (int i = 0; i < ((GuildObject) object).core.getActiveConnectionsMap().size(); i++) { + ((GuildObject) object).core.getActiveConnectionsMap().get(i).getSession().write(buffer); + } + + break; + } + } + } + case 6: + { + switch (updateType) { + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + { + buffer = createDeltaObject(updateType, buffer, buffer.position()); + //System.out.println("Packet: " + bytesToHex(buffer.array())); + zoneUpdates.add(buffer); + break; + } + default: + { + return; + } + } + } + } + } + } + @Override public void sendBaselines() { // TODO Auto-generated method stub diff --git a/src/resources/objects/guild/GuildObject.java b/src/resources/objects/guild/GuildObject.java index e06f7767..f268af3b 100644 --- a/src/resources/objects/guild/GuildObject.java +++ b/src/resources/objects/guild/GuildObject.java @@ -21,11 +21,15 @@ ******************************************************************************/ package resources.objects.guild; -import java.util.ArrayList; -import java.util.List; +import org.apache.mina.core.buffer.IoBuffer; -import resources.objects.GCWZone; +import main.NGECore; + +import resources.objects.CurrentServerGCWZoneHistory; +import resources.objects.CurrentServerGCWZonePercent; import resources.objects.Guild; +import resources.objects.OtherServerGCWZonePercent; +import resources.objects.SWGList; import com.sleepycat.persist.model.NotPersistent; @@ -37,6 +41,10 @@ import engine.resources.scene.Quaternion; public class GuildObject extends SWGObject { + protected NGECore core; + @NotPersistent + private GuildMessageBuilder messageBuilder = new GuildMessageBuilder(this); + // GILD 3 private float complexity = 0x803F0F00; private String STFFile = "string_id_table"; @@ -44,46 +52,24 @@ public class GuildObject extends SWGObject { private String STFName = ""; private String customName = ""; private int volume = 0; - private List guildList = new ArrayList(); - @NotPersistent - private int guildListUpdateCounter = 0; + private SWGList guildList = new SWGList(messageBuilder, 3, 4); // GILD 6 private int serverId = 0x00000041; //private String STFName = "string_id_table"; private int unknown1 = 0; private short unknown2 = 0; - - private List currentServerGCWZonePercentList = new ArrayList(); - @NotPersistent - private int currentServerGCWZonePercentListUpdateCounter = 0; - - private List currentServerGCWTotalPercentList = new ArrayList(); - @NotPersistent - private int currentServerGCWTotalPercentListUpdateCounter = 0; - - private List currentServerGCWZoneHistoryList = new ArrayList(); - @NotPersistent - private int currentServerGCWZoneHistoryListUpdateCounter = 0; + private SWGList currentServerGCWZonePercentList = new SWGList(messageBuilder, 6, 2); + private SWGList currentServerGCWTotalPercentList = new SWGList(messageBuilder, 6, 3); + private SWGList currentServerGCWZoneHistoryList = new SWGList(messageBuilder, 6, 4); + private SWGList currentServerGCWTotalHistoryList = new SWGList(messageBuilder, 6, 5); + private SWGList otherServerGCWZonePercentList = new SWGList(messageBuilder, 6, 6); + private SWGList otherServerGCWTotalPercentList = new SWGList(messageBuilder, 6, 7); + private int unknown3 = 5; - private List currentServerGCWTotalHistoryList = new ArrayList(); - @NotPersistent - private int currentServerGCWTotalHistoryListUpdateCounter = 0; - - private List otherServerGCWZonePercentList = new ArrayList(); - @NotPersistent - private int otherServerGCWZonePercentListUpdateCounter = 0; - - private List otherServerGCWTotalPercentList = new ArrayList(); - @NotPersistent - private int otherServerGCWTotalPercentListUpdateCounter = 0; - - @NotPersistent - private GuildMessageBuilder messageBuilder; - - public GuildObject(long objectID, Planet planet, Point3D position, Quaternion orientation, String Template) { + public GuildObject(NGECore core, long objectID, Planet planet, Point3D position, Quaternion orientation, String Template) { super(objectID, planet, position, orientation, Template); - messageBuilder = new GuildMessageBuilder(this); + this.core = core; } public float getComplexity() { @@ -96,6 +82,8 @@ public class GuildObject extends SWGObject { synchronized(objectMutex) { this.complexity = complexity; } + + notifyAll(messageBuilder.buildComplexity(complexity)); } public String getSTFFile() { @@ -108,6 +96,8 @@ public class GuildObject extends SWGObject { synchronized(objectMutex) { this.STFFile = STFFile; } + + notifyAll(messageBuilder.buildSTF(STFFile, STFSpacer, STFName)); } public int getSTFSpacer() { @@ -120,6 +110,8 @@ public class GuildObject extends SWGObject { synchronized(objectMutex) { this.STFSpacer = STFSpacer; } + + notifyAll(messageBuilder.buildSTF(STFFile, STFSpacer, STFName)); } public String getSTFName() { @@ -132,6 +124,8 @@ public class GuildObject extends SWGObject { synchronized(objectMutex) { this.STFName = STFName; } + + notifyAll(messageBuilder.buildSTF(STFFile, STFSpacer, STFName)); } public String getCustomName() { @@ -144,6 +138,8 @@ public class GuildObject extends SWGObject { synchronized(objectMutex) { this.customName = customName; } + + notifyAll(messageBuilder.buildCustomName(customName)); } public int getVolume() { @@ -156,24 +152,14 @@ public class GuildObject extends SWGObject { synchronized(objectMutex) { this.volume = volume; } + + notifyAll(messageBuilder.buildVolume(volume)); } - public List getGuildList() { + public SWGList getGuildList() { return guildList; } - public int getGuildListUpdateCounter() { - synchronized(objectMutex) { - return guildListUpdateCounter; - } - } - - public void setGuildListUpdateCounter(int guildListUpdateCounter) { - synchronized(objectMutex) { - this.guildListUpdateCounter = guildListUpdateCounter; - } - } - public int getServerId() { synchronized(objectMutex) { return serverId; @@ -184,6 +170,8 @@ public class GuildObject extends SWGObject { synchronized(objectMutex) { this.serverId = serverId; } + + notifyAll(messageBuilder.buildServerId(serverId)); } public int getUnknown1() { @@ -196,6 +184,8 @@ public class GuildObject extends SWGObject { synchronized(objectMutex) { this.unknown1 = unknown1; } + + notifyAll(messageBuilder.buildUnknowns(unknown1, unknown2)); } public short getUnknown2() { @@ -208,101 +198,53 @@ public class GuildObject extends SWGObject { synchronized(objectMutex) { this.unknown2 = unknown2; } + + notifyAll(messageBuilder.buildUnknowns(unknown1, unknown2)); } - public List getCurrentServerGCWZonePercentList() { + public SWGList getCurrentServerGCWZonePercentList() { return currentServerGCWZonePercentList; } - public int getCurrentServerGCWZonePercentListUpdateCounter() { - synchronized(objectMutex) { - return currentServerGCWZonePercentListUpdateCounter; - } - } - - public void setCurrentServerGCWZonePercentListUpdateCounter(int currentServerGCWZonePercentListUpdateCounter) { - synchronized(objectMutex) { - this.currentServerGCWZonePercentListUpdateCounter = currentServerGCWZonePercentListUpdateCounter; - } - } - - public List getCurrentServerGCWTotalPercentList() { + public SWGList getCurrentServerGCWTotalPercentList() { return currentServerGCWTotalPercentList; } - public int getCurrentServerGCWTotalPercentListUpdateCounter() { - synchronized(objectMutex) { - return currentServerGCWTotalPercentListUpdateCounter; - } - } - - public void setCurrentServerGCWTotalPercentListUpdateCounter(int currentServerGCWTotalPercentListUpdateCounter) { - synchronized(objectMutex) { - this.currentServerGCWTotalPercentListUpdateCounter = currentServerGCWTotalPercentListUpdateCounter; - } - } - - public List getCurrentServerGCWZoneHistoryList() { + public SWGList getCurrentServerGCWZoneHistoryList() { return currentServerGCWZoneHistoryList; } - public int getCurrentServerGCWZoneHistoryListUpdateCounter() { - synchronized(objectMutex) { - return currentServerGCWZoneHistoryListUpdateCounter; - } - } - - public void setCurrentServerGCWZoneHistoryListUpdateCounter(int currentServerGCWZoneHistoryListUpdateCounter) { - synchronized(objectMutex) { - this.currentServerGCWZoneHistoryListUpdateCounter = currentServerGCWZoneHistoryListUpdateCounter; - } - } - - public List getCurrentServerGCWTotalHistoryList() { + public SWGList getCurrentServerGCWTotalHistoryList() { return currentServerGCWTotalHistoryList; } - public int getCurrentServerGCWTotalHistoryListUpdateCounter() { - synchronized(objectMutex) { - return currentServerGCWTotalHistoryListUpdateCounter; - } - } - - public void setCurrentServerGCWTotalHistoryListUpdateCounter(int currentServerGCWTotalHistoryListUpdateCounter) { - synchronized(objectMutex) { - this.currentServerGCWTotalHistoryListUpdateCounter = currentServerGCWTotalHistoryListUpdateCounter; - } - } - - public List getOtherServerGCWZonePercentList() { + public SWGList getOtherServerGCWZonePercentList() { return otherServerGCWZonePercentList; } - public int getOtherServerGCWZonePercentListUpdateCounter() { - synchronized(objectMutex) { - return otherServerGCWZonePercentListUpdateCounter; - } - } - - public void setOtherServerGCWZonePercentListUpdateCounter(int otherServerGCWZonePercentListUpdateCounter) { - synchronized(objectMutex) { - this.otherServerGCWZonePercentListUpdateCounter = otherServerGCWZonePercentListUpdateCounter; - } - } - - public List getOtherServerGCWTotalPercentList() { + public SWGList getOtherServerGCWTotalPercentList() { return otherServerGCWTotalPercentList; } - public int getOtherServerGCWTotalPercentListUpdateCounter() { + public int getUnknown3() { synchronized(objectMutex) { - return otherServerGCWTotalPercentListUpdateCounter; + return unknown3; } } - public void setOtherServerGCWTotalPercentListUpdateCounter(int otherServerGCWTotalPercentListUpdateCounter) { + public void setUnknown3(int unknown3) { synchronized(objectMutex) { - this.otherServerGCWTotalPercentListUpdateCounter = otherServerGCWTotalPercentListUpdateCounter; + this.unknown3 = unknown3; + } + + notifyAll(messageBuilder.buildUnknown3(unknown3)); + } + + public void sendGCWUpdate() { + IoBuffer buffer = messageBuilder.buildGCWDelta(); + + if (buffer != null) { + notifyAll(buffer); } } @@ -311,6 +253,20 @@ public class GuildObject extends SWGObject { destination.getSession().write(messageBuilder.buildBaseline3()); destination.getSession().write(messageBuilder.buildBaseline6()); } - + + private void notifyAll(IoBuffer buffer) { + //for (int i = 0; i < core.getActiveConnectionsMap().size(); i++) { + // core.getActiveConnectionsMap().get(i).getSession().write(buffer); + //} + System.out.println("Notifying all..."); + synchronized(core.getActiveConnectionsMap()) { + for (Client client : core.getActiveConnectionsMap().values()) { + System.out.println("Notifying..." + client.getParent().getCustomName()); + client.getSession().write(buffer); + System.out.println("Notified them."); + System.out.println("Packet: " + buffer.getHexDump()); + } + } + } } diff --git a/src/resources/objects/player/PlayerMessageBuilder.java b/src/resources/objects/player/PlayerMessageBuilder.java index 381ae5f4..abb2dfcb 100644 --- a/src/resources/objects/player/PlayerMessageBuilder.java +++ b/src/resources/objects/player/PlayerMessageBuilder.java @@ -390,9 +390,21 @@ public class PlayerMessageBuilder extends ObjectMessageBuilder { } } + + public IoBuffer buildTitleDelta(String title) { + + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.put(getAsciiString(title)); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("PLAY", (byte) 3, (short) 1, (short) 1, buffer, size + 4); + + return buffer; + + } @Override - public void sendListDelta(short updateType, IoBuffer buffer) { + public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) { // TODO Auto-generated method stub } diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index d41823d3..4472829c 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -134,6 +134,8 @@ public class PlayerObject extends SWGObject { synchronized(objectMutex) { this.title = title; } + + notifyObservers(messageBuilder.buildTitleDelta(title), true); } public String getProfession() { diff --git a/src/resources/objects/tangible/TangibleMessageBuilder.java b/src/resources/objects/tangible/TangibleMessageBuilder.java index e36ad1d8..b15e4bbd 100644 --- a/src/resources/objects/tangible/TangibleMessageBuilder.java +++ b/src/resources/objects/tangible/TangibleMessageBuilder.java @@ -124,7 +124,7 @@ public class TangibleMessageBuilder extends ObjectMessageBuilder { } @Override - public void sendListDelta(short updateType, IoBuffer buffer) { + public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) { // TODO Auto-generated method stub } diff --git a/src/resources/objects/weapon/WeaponMessageBuilder.java b/src/resources/objects/weapon/WeaponMessageBuilder.java index 7251fb1f..6e722042 100644 --- a/src/resources/objects/weapon/WeaponMessageBuilder.java +++ b/src/resources/objects/weapon/WeaponMessageBuilder.java @@ -134,7 +134,7 @@ public class WeaponMessageBuilder extends ObjectMessageBuilder { } @Override - public void sendListDelta(short updateType, IoBuffer buffer) { + public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) { // TODO Auto-generated method stub } diff --git a/src/services/gcw/GCWService.java b/src/services/gcw/GCWService.java index f3668f1e..b1fd9b9c 100644 --- a/src/services/gcw/GCWService.java +++ b/src/services/gcw/GCWService.java @@ -28,7 +28,9 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import resources.objects.GCWZone; +import resources.objects.CurrentServerGCWZoneHistory; +import resources.objects.CurrentServerGCWZonePercent; +import resources.objects.OtherServerGCWZonePercent; import resources.objects.guild.GuildObject; import main.NGECore; @@ -41,32 +43,26 @@ public class GCWService implements INetworkDispatch { private NGECore core; private GuildObject object; - private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - - List zoneList = Arrays.asList(new String[] { "corellia_airspace", "corellia_pve", "corellia_pvp", "dantooine_airspace", "dantooine_pve", "dantooine_pvp", "dathomir_airspace", "dathomir_pve", "dathomir_pvp", "endor_airspace", "endor_pve", "endor_pvp", "endor_pvp_battlefield", "gcw_region_corellia_1", "gcw_region_corellia_10", "gcw_region_corellia_11", "gcw_region_corellia_12", "gcw_region_corellia_13", "gcw_region_corellia_14", "gcw_region_corellia_2", "gcw_region_corellia_3", "gcw_region_corellia_4", "gcw_region_corellia_5", "gcw_region_corellia_6", "gcw_region_corellia_7", "gcw_region_corellia_8", "gcw_region_corellia_9", "gcw_region_dantooine_1", "gcw_region_dantooine_10", "gcw_region_dantooine_11", "gcw_region_dantooine_12", "gcw_region_dantooine_13", "gcw_region_dantooine_14", "gcw_region_dantooine_15", "gcw_region_dantooine_16", "gcw_region_dantooine_17", "gcw_region_dantooine_2", "gcw_region_dantooine_3", "gcw_region_dantooine_4", "gcw_region_dantooine_5", "gcw_region_dantooine_6", "gcw_region_dantooine_7", "gcw_region_dantooine_8", "gcw_region_dantooine_9", "gcw_region_dathomir_1", "gcw_region_dathomir_10", "gcw_region_dathomir_11", "gcw_region_dathomir_12", "gcw_region_dathomir_13", "gcw_region_dathomir_2", "gcw_region_dathomir_3", "gcw_region_dathomir_4", "gcw_region_dathomir_5", "gcw_region_dathomir_6", "gcw_region_dathomir_7", "gcw_region_dathomir_8", "gcw_region_dathomir_9", "gcw_region_endor_1", "gcw_region_endor_10", "gcw_region_endor_11", "gcw_region_endor_12", "gcw_region_endor_13", "gcw_region_endor_14", "gcw_region_endor_15", "gcw_region_endor_16", "gcw_region_endor_2", "gcw_region_endor_3", "gcw_region_endor_4", "gcw_region_endor_5", "gcw_region_endor_6", "gcw_region_endor_7", "gcw_region_endor_8", "gcw_region_endor_9", "gcw_region_lok_1", "gcw_region_lok_10", "gcw_region_lok_11", "gcw_region_lok_12", "gcw_region_lok_13", "gcw_region_lok_14", "gcw_region_lok_2", "gcw_region_lok_3", "gcw_region_lok_4", "gcw_region_lok_5", "gcw_region_lok_6", "gcw_region_lok_7", "gcw_region_lok_8", "gcw_region_lok_9", "gcw_region_naboo_1", "gcw_region_naboo_10", "gcw_region_naboo_11", "gcw_region_naboo_12", "gcw_region_naboo_13", "gcw_region_naboo_14", "gcw_region_naboo_2", "gcw_region_naboo_3", "gcw_region_naboo_4", "gcw_region_naboo_5", "gcw_region_naboo_6", "gcw_region_naboo_7", "gcw_region_naboo_8", "gcw_region_naboo_9", "gcw_region_rori_1", "gcw_region_rori_10", "gcw_region_rori_11", "gcw_region_rori_12", "gcw_region_rori_13", "gcw_region_rori_2", "gcw_region_rori_3", "gcw_region_rori_4", "gcw_region_rori_5", "gcw_region_rori_6", "gcw_region_rori_7", "gcw_region_rori_8", "gcw_region_rori_9", "gcw_region_talus_1", "gcw_region_talus_10", "gcw_region_talus_11", "gcw_region_talus_12", "gcw_region_talus_13", "gcw_region_talus_14", "gcw_region_talus_15", "gcw_region_talus_16", "gcw_region_talus_2", "gcw_region_talus_3", "gcw_region_talus_4", "gcw_region_talus_5", "gcw_region_talus_6", "gcw_region_talus_7", "gcw_region_talus_8", "gcw_region_talus_9", "gcw_region_tatooine_1", "gcw_region_tatooine_10", "gcw_region_tatooine_11", "gcw_region_tatooine_12", "gcw_region_tatooine_13", "gcw_region_tatooine_2", "gcw_region_tatooine_3", "gcw_region_tatooine_4", "gcw_region_tatooine_5", "gcw_region_tatooine_6", "gcw_region_tatooine_7", "gcw_region_tatooine_8", "gcw_region_tatooine_9", "gcw_region_yavin4_1", "gcw_region_yavin4_10", "gcw_region_yavin4_11", "gcw_region_yavin4_12", "gcw_region_yavin4_13", "gcw_region_yavin4_14", "gcw_region_yavin4_15", "gcw_region_yavin4_16", "gcw_region_yavin4_17", "gcw_region_yavin4_18", "gcw_region_yavin4_2", "gcw_region_yavin4_3", "gcw_region_yavin4_4", "gcw_region_yavin4_5", "gcw_region_yavin4_6", "gcw_region_yavin4_7", "gcw_region_yavin4_8", "gcw_region_yavin4_9", "lok_airspace", "lok_pve", "lok_pvp", "naboo_airspace", "naboo_pve", "naboo_pvp", "rori_airspace", "rori_pve", "rori_pvp", "space_corellia_space_pve", "space_corellia_space_pvp", "space_dantooine_space_pve", "space_dantooine_space_pvp", "space_dathomir_space_pve", "space_dathomir_space_pvp", "space_endor_space_pve", "space_endor_space_pvp", "space_lok_space_pve", "space_lok_space_pvp", "space_naboo_space_pve", "space_naboo_space_pvp", "space_tatooine_space_pve", "space_tatooine_space_pvp", "space_yavin4_space_pve", "space_yavin4_space_pvp", "talus_airspace", "talus_pve", "talus_pvp", "tatooine_airspace", "tatooine_pve", "tatooine_pvp", "yavin4_airspace", "yavin4_pve", "yavin4_pvp", "yavin4_pvp_battlefield" }); - List totalList = Arrays.asList(new String[] { "corellia", "dantooine", "dathomir", "endor", "galaxy", "lok", "naboo", "rori", "talus", "tatooine", "yavin4" }); - + + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + private List zoneList = Arrays.asList(new String[] { "corellia_airspace", "corellia_pve", "corellia_pvp", "dantooine_airspace", "dantooine_pve", "dantooine_pvp", "dathomir_airspace", "dathomir_pve", "dathomir_pvp", "endor_airspace", "endor_pve", "endor_pvp", "endor_pvp_battlefield", "gcw_region_corellia_1", "gcw_region_corellia_10", "gcw_region_corellia_11", "gcw_region_corellia_12", "gcw_region_corellia_13", "gcw_region_corellia_14", "gcw_region_corellia_2", "gcw_region_corellia_3", "gcw_region_corellia_4", "gcw_region_corellia_5", "gcw_region_corellia_6", "gcw_region_corellia_7", "gcw_region_corellia_8", "gcw_region_corellia_9", "gcw_region_dantooine_1", "gcw_region_dantooine_10", "gcw_region_dantooine_11", "gcw_region_dantooine_12", "gcw_region_dantooine_13", "gcw_region_dantooine_14", "gcw_region_dantooine_15", "gcw_region_dantooine_16", "gcw_region_dantooine_17", "gcw_region_dantooine_2", "gcw_region_dantooine_3", "gcw_region_dantooine_4", "gcw_region_dantooine_5", "gcw_region_dantooine_6", "gcw_region_dantooine_7", "gcw_region_dantooine_8", "gcw_region_dantooine_9", "gcw_region_dathomir_1", "gcw_region_dathomir_10", "gcw_region_dathomir_11", "gcw_region_dathomir_12", "gcw_region_dathomir_13", "gcw_region_dathomir_2", "gcw_region_dathomir_3", "gcw_region_dathomir_4", "gcw_region_dathomir_5", "gcw_region_dathomir_6", "gcw_region_dathomir_7", "gcw_region_dathomir_8", "gcw_region_dathomir_9", "gcw_region_endor_1", "gcw_region_endor_10", "gcw_region_endor_11", "gcw_region_endor_12", "gcw_region_endor_13", "gcw_region_endor_14", "gcw_region_endor_15", "gcw_region_endor_16", "gcw_region_endor_2", "gcw_region_endor_3", "gcw_region_endor_4", "gcw_region_endor_5", "gcw_region_endor_6", "gcw_region_endor_7", "gcw_region_endor_8", "gcw_region_endor_9", "gcw_region_lok_1", "gcw_region_lok_10", "gcw_region_lok_11", "gcw_region_lok_12", "gcw_region_lok_13", "gcw_region_lok_14", "gcw_region_lok_2", "gcw_region_lok_3", "gcw_region_lok_4", "gcw_region_lok_5", "gcw_region_lok_6", "gcw_region_lok_7", "gcw_region_lok_8", "gcw_region_lok_9", "gcw_region_naboo_1", "gcw_region_naboo_10", "gcw_region_naboo_11", "gcw_region_naboo_12", "gcw_region_naboo_13", "gcw_region_naboo_14", "gcw_region_naboo_2", "gcw_region_naboo_3", "gcw_region_naboo_4", "gcw_region_naboo_5", "gcw_region_naboo_6", "gcw_region_naboo_7", "gcw_region_naboo_8", "gcw_region_naboo_9", "gcw_region_rori_1", "gcw_region_rori_10", "gcw_region_rori_11", "gcw_region_rori_12", "gcw_region_rori_13", "gcw_region_rori_2", "gcw_region_rori_3", "gcw_region_rori_4", "gcw_region_rori_5", "gcw_region_rori_6", "gcw_region_rori_7", "gcw_region_rori_8", "gcw_region_rori_9", "gcw_region_talus_1", "gcw_region_talus_10", "gcw_region_talus_11", "gcw_region_talus_12", "gcw_region_talus_13", "gcw_region_talus_14", "gcw_region_talus_15", "gcw_region_talus_16", "gcw_region_talus_2", "gcw_region_talus_3", "gcw_region_talus_4", "gcw_region_talus_5", "gcw_region_talus_6", "gcw_region_talus_7", "gcw_region_talus_8", "gcw_region_talus_9", "gcw_region_tatooine_1", "gcw_region_tatooine_10", "gcw_region_tatooine_11", "gcw_region_tatooine_12", "gcw_region_tatooine_13", "gcw_region_tatooine_2", "gcw_region_tatooine_3", "gcw_region_tatooine_4", "gcw_region_tatooine_5", "gcw_region_tatooine_6", "gcw_region_tatooine_7", "gcw_region_tatooine_8", "gcw_region_tatooine_9", "gcw_region_yavin4_1", "gcw_region_yavin4_10", "gcw_region_yavin4_11", "gcw_region_yavin4_12", "gcw_region_yavin4_13", "gcw_region_yavin4_14", "gcw_region_yavin4_15", "gcw_region_yavin4_16", "gcw_region_yavin4_17", "gcw_region_yavin4_18", "gcw_region_yavin4_2", "gcw_region_yavin4_3", "gcw_region_yavin4_4", "gcw_region_yavin4_5", "gcw_region_yavin4_6", "gcw_region_yavin4_7", "gcw_region_yavin4_8", "gcw_region_yavin4_9", "lok_airspace", "lok_pve", "lok_pvp", "naboo_airspace", "naboo_pve", "naboo_pvp", "rori_airspace", "rori_pve", "rori_pvp", "space_corellia_space_pve", "space_corellia_space_pvp", "space_dantooine_space_pve", "space_dantooine_space_pvp", "space_dathomir_space_pve", "space_dathomir_space_pvp", "space_endor_space_pve", "space_endor_space_pvp", "space_lok_space_pve", "space_lok_space_pvp", "space_naboo_space_pve", "space_naboo_space_pvp", "space_tatooine_space_pve", "space_tatooine_space_pvp", "space_yavin4_space_pve", "space_yavin4_space_pvp", "talus_airspace", "talus_pve", "talus_pvp", "tatooine_airspace", "tatooine_pve", "tatooine_pvp", "yavin4_airspace", "yavin4_pve", "yavin4_pvp", "yavin4_pvp_battlefield" }); + private List totalList = Arrays.asList(new String[] { "corellia", "dantooine", "dathomir", "endor", "galaxy", "lok", "naboo", "rori", "talus", "tatooine", "yavin4" }); + public GCWService(final NGECore core) { this.core = core; - - object = this.core.guildService.getGuildObject(); + this.object = this.core.guildService.getGuildObject(); for (int i = 0; i < zoneList.size(); i++) { - object.getCurrentServerGCWZonePercentList().add(new GCWZone(zoneList.get(i))); - object.getCurrentServerGCWZoneHistoryList().add(new GCWZone(zoneList.get(i))); - object.getOtherServerGCWZonePercentList().add(new GCWZone(zoneList.get(i))); - object.setCurrentServerGCWZonePercentListUpdateCounter(object.getCurrentServerGCWZonePercentListUpdateCounter() + 1); - object.setCurrentServerGCWZoneHistoryListUpdateCounter(object.getCurrentServerGCWZoneHistoryListUpdateCounter() + 1); - object.setOtherServerGCWZonePercentListUpdateCounter(object.getOtherServerGCWZonePercentListUpdateCounter() + 1); + object.getCurrentServerGCWZonePercentList().add(new CurrentServerGCWZonePercent(zoneList.get(i))); + object.getCurrentServerGCWZoneHistoryList().add(new CurrentServerGCWZoneHistory(zoneList.get(i))); + object.getOtherServerGCWZonePercentList().add(new OtherServerGCWZonePercent(zoneList.get(i))); } for (int i = 0; i < totalList.size(); i++) { - object.getCurrentServerGCWTotalPercentList().add(new GCWZone(totalList.get(i))); - object.getCurrentServerGCWTotalHistoryList().add(new GCWZone(totalList.get(i))); - object.getOtherServerGCWTotalPercentList().add(new GCWZone(totalList.get(i))); - object.setCurrentServerGCWTotalPercentListUpdateCounter(object.getCurrentServerGCWTotalPercentListUpdateCounter() + 1); - object.setCurrentServerGCWTotalHistoryListUpdateCounter(object.getCurrentServerGCWTotalHistoryListUpdateCounter() + 1); - object.setOtherServerGCWTotalPercentListUpdateCounter(object.getOtherServerGCWTotalPercentListUpdateCounter() + 1); + object.getCurrentServerGCWTotalPercentList().add(new CurrentServerGCWZonePercent(totalList.get(i))); + object.getCurrentServerGCWTotalHistoryList().add(new CurrentServerGCWZoneHistory(totalList.get(i))); + object.getOtherServerGCWTotalPercentList().add(new OtherServerGCWZonePercent(totalList.get(i))); } // Update the GCW Zones every minute as in live @@ -74,33 +70,46 @@ public class GCWService implements INetworkDispatch { @Override public void run() { - synchronized(core.getActiveConnectionsMap()) { - for (Client c : core.getActiveConnectionsMap().values()) { - if (c.getParent() != null) { - addGCWPointsToZonesWithFactionalPresence(c); - removeGCWPointFromZonesWithNoFactionalPresence(c); - } - } - } + //object.sendGCWUpdate(); + //addGCWPointsToZonesWithFactionalPresence(new Client()); + //removeGCWPointFromZonesWithNoFactionalPresence(new Client()); } }, 1, 1, TimeUnit.MINUTES); - // Reset weak GCW zones every 2 days as in live + // Update other server GCW Zones every 15 minutes (roughly like live I think) scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { - synchronized(core.getActiveConnectionsMap()) { - for (Client c : core.getActiveConnectionsMap().values()) { - if (c.getParent() != null) { - resetWeakGCWZones(); - } - } + /* + for (int i = 0; i < object.getOtherServerGCWZonePercentList().size(); i++) { + object.getOtherServerGCWZonePercentList().get(i).setPercent(object.getCurrentServerGCWZonePercentList().get(i).getPercent()); + object.getOtherServerGCWZonePercentList().set(i, object.getOtherServerGCWZonePercentList().get(i)); } + + for (int i = 0; i < object.getOtherServerGCWTotalPercentList().size(); i++) { + object.getOtherServerGCWTotalPercentList().get(i).setPercent(object.getCurrentServerGCWTotalPercentList().get(i).getPercent()); + object.getOtherServerGCWZonePercentList().set(i, object.getOtherServerGCWZonePercentList().get(i)); + } + */ } - }, 2, 2, TimeUnit.DAYS); + //}, 15, 15, TimeUnit.MINUTES); + }, 2, 5, TimeUnit.MINUTES); + + // Reset weak GCW Zones every 2 days as in live + scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + /* + resetWeakGCWZones(); + */ + } + + //}, 2, 2, TimeUnit.DAYS); + }, 2, 5, TimeUnit.MINUTES); } private void addGCWPointsToZonesWithFactionalPresence(Client client) { @@ -112,7 +121,23 @@ public class GCWService implements INetworkDispatch { } private void resetWeakGCWZones() { + for (int i = 0; i < object.getCurrentServerGCWZonePercentList().size(); i++) { + CurrentServerGCWZonePercent zone = object.getCurrentServerGCWZonePercentList().get(i); + + if (zone.getGCWPoints() == 0 && zone.getPercent() != 50) { + zone.setPercent(50, object.getCurrentServerGCWZoneHistoryList()); + object.getCurrentServerGCWZonePercentList().set(i, zone); + } + } + for (int i = 0; i < object.getCurrentServerGCWTotalPercentList().size(); i++) { + CurrentServerGCWZonePercent zone = object.getCurrentServerGCWTotalPercentList().get(i); + + if (zone.getGCWPoints() == 0 && zone.getPercent() != 50) { + zone.setPercent(50, object.getCurrentServerGCWTotalHistoryList()); + object.getCurrentServerGCWTotalPercentList().set(i, zone); + } + } } @Override diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 6c3d4f83..79ac9bee 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -155,7 +155,7 @@ public class ObjectService implements INetworkDispatch { } else if(Template.startsWith("object/guild")) { - object = new GuildObject(objectID, planet, position, orientation, Template); + object = new GuildObject(core, objectID, planet, position, orientation, Template); } else {