Refactored SUI windows

This commit is contained in:
Josh-Larson
2024-06-19 13:45:10 -05:00
parent 99cdc1136a
commit e3a7825655
6 changed files with 448 additions and 536 deletions

View File

@@ -1,5 +1,5 @@
/***********************************************************************************
* Copyright (c) 2018 /// Project SWG /// www.projectswg.com *
* Copyright (c) 2024 /// 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. *
@@ -24,10 +24,8 @@
* 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.sui;
package com.projectswg.common.data.sui
import java.util.Map;
import java.util.function.BiConsumer
public interface ISuiCallback {
void handleEvent(SuiEvent event, Map<String, String> parameters);
}
typealias ISuiCallback = BiConsumer<SuiEvent, Map<String, String>>

View File

@@ -1,289 +0,0 @@
/***********************************************************************************
* Copyright (c) 2018 /// 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.sui;
import me.joshlarson.jlcommon.log.Log;
import com.projectswg.common.encoding.Encodable;
import com.projectswg.common.network.NetBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SuiBaseWindow implements Encodable {
private int id;
private String suiScript;
private long rangeObjId;
private float maxDistance = 0;
private List<SuiComponent> components = new ArrayList<>();
private Map<String, ISuiCallback> callbacks;
private boolean hasSubscriptionComponent = false;
public SuiBaseWindow() {
}
public SuiBaseWindow(String suiScript) {
this.suiScript = suiScript;
}
public final void clearDataSource(String dataSource) {
SuiComponent component = new SuiComponent(SuiComponent.Type.CLEAR_DATA_SOURCE, dataSource);
components.add(component);
}
public final void addChildWidget(String type, String childWidget, String parentWidget) {
SuiComponent component = new SuiComponent(SuiComponent.Type.ADD_CHILD_WIDGET, parentWidget);
component.addNarrowParam(type);
component.addNarrowParam(childWidget);
components.add(component);
}
public final void setProperty(String widget, String property, String value) {
SuiComponent component = new SuiComponent(SuiComponent.Type.SET_PROPERTY, widget);
component.addNarrowParam(property);
component.addWideParam(value);
components.add(component);
}
public final void addDataItem(String dataSource, String name, String value) {
SuiComponent component = new SuiComponent(SuiComponent.Type.ADD_DATA_ITEM, dataSource);
component.addNarrowParam(name);
component.addWideParam(value);
components.add(component);
}
protected void subscribeToEvent(int event, String widgetSource, String callback) {
SuiComponent component = getSubscriptionForEvent(event, widgetSource);
if (component != null) {
Log.i("Added event callback %d to %s when the event is already subscribed to, replacing callback to %s", event, widgetSource, callback);
component.getNarrowParams().set(2, callback);
} else {
component = new SuiComponent(SuiComponent.Type.SUBSCRIBE_TO_EVENT, widgetSource);
component.addNarrowParam(getWrappedEventString(event));
component.addNarrowParam(callback);
components.add(component);
}
if (!hasSubscriptionComponent())
hasSubscriptionComponent = true;
}
protected void subscribeToPropertyEvent(int event, String widgetSource, String propertyWidget, String propertyName) {
SuiComponent component = getSubscriptionForEvent(event, widgetSource);
if (component != null) {
// This component already has the trigger and source param, just need to add the widget and property
// for client to return the value to the server
component.addNarrowParam(propertyWidget);
component.addNarrowParam(propertyName);
} else {
component = new SuiComponent(SuiComponent.Type.SUBSCRIBE_TO_EVENT, widgetSource);
component.addNarrowParam(getWrappedEventString(event));
component.addNarrowParam("");
component.addNarrowParam(propertyWidget);
component.addNarrowParam(propertyName);
components.add(component);
}
if (!hasSubscriptionComponent())
hasSubscriptionComponent = true;
}
public final void addDataSourceContainer(String dataSourceContainer, String name, String value) {
SuiComponent component = new SuiComponent(SuiComponent.Type.ADD_DATA_SOURCE_CONTAINER, dataSourceContainer);
component.addNarrowParam(name);
component.addWideParam(value);
components.add(component);
}
public final void clearDataSourceContainer(String dataSourceContainer) {
SuiComponent component = new SuiComponent(SuiComponent.Type.CLEAR_DATA_SOURCE_CONTAINER, dataSourceContainer);
components.add(component);
}
public final void addDataSource(String dataSource, String name, String value) {
SuiComponent component = new SuiComponent(SuiComponent.Type.ADD_DATA_SOURCE, dataSource);
component.addNarrowParam(name);
component.addWideParam(value);
components.add(component);
}
public final void addReturnableProperty(SuiEvent event, String source, String widget, String property) {
subscribeToPropertyEvent(event.getValue(), source, widget, property);
}
public final void addReturnableProperty(SuiEvent event, String widget, String property) {
addReturnableProperty(event, "", widget, property);
}
public final void addReturnableProperty(String widget, String property) {
subscribeToPropertyEvent(SuiEvent.OK_PRESSED.getValue(), "", widget, property);
subscribeToPropertyEvent(SuiEvent.CANCEL_PRESSED.getValue(), "", widget, property);
}
public final void addCallback(SuiEvent event, String source, String name, ISuiCallback callback) {
subscribeToEvent(event.getValue(), source, name);
addJavaCallback(name, callback);
}
public final void addCallback(SuiEvent event, String name, ISuiCallback callback) {
addCallback(event, "", name, callback);
}
public final void addCallback(String source, String name, ISuiCallback callback) {
subscribeToEvent(SuiEvent.OK_PRESSED.getValue(), source, name);
subscribeToEvent(SuiEvent.CANCEL_PRESSED.getValue(), source, name);
addJavaCallback(name, callback);
}
public final void addCallback(String name, ISuiCallback callback) {
addCallback("", name, callback);
}
public final SuiComponent getSubscriptionForEvent(int event, String widget) {
for (SuiComponent component : components) {
if (component.getType() != SuiComponent.Type.SUBSCRIBE_TO_EVENT)
continue;
int eventType = component.getSubscribedToEventType();
if (eventType == event && component.getTarget().equals(widget))
return component;
}
return null;
}
public final SuiComponent getSubscriptionByIndex(int index) {
int count = 0;
for (SuiComponent component : components) {
if (component.getType() == SuiComponent.Type.SUBSCRIBE_TO_EVENT) {
if (index == count) return component;
else count++;
}
}
return null;
}
public final long getRangeObjId() {
return rangeObjId;
}
public final void setRangeObjId(long rangeObjId) {
this.rangeObjId = rangeObjId;
}
public final int getId() {
return id;
}
public final void setId(int id) {
this.id = id;
}
public final String getSuiScript() {
return suiScript;
}
public final float getMaxDistance() {
return maxDistance;
}
public final void setMaxDistance(float maxDistance) {
this.maxDistance = maxDistance;
}
public final List<SuiComponent> getComponents() {
return components;
}
public final ISuiCallback getJavaCallback(String name) {
return callbacks != null ? callbacks.get(name) : null;
}
public final boolean hasJavaCallback(String name) {
return callbacks != null && callbacks.containsKey(name);
}
public final boolean hasSubscriptionComponent() {
return hasSubscriptionComponent;
}
private void addJavaCallback(String name, ISuiCallback callback) {
if (callbacks == null) callbacks = new HashMap<>();
callbacks.put(name, callback);
}
private String getWrappedEventString(int event) {
return new String(new byte[]{(byte) event}, StandardCharsets.UTF_8);
}
@Override
public byte[] encode() {
NetBuffer data = NetBuffer.allocate(getLength());
data.addInt(id);
data.addAscii(suiScript);
data.addList(components);
data.addLong(rangeObjId);
data.addFloat(maxDistance);
data.addLong(0); // Window Location?
data.addInt(0);
return data.array();
}
@Override
public void decode(NetBuffer data) {
id = data.getInt();
suiScript = data.getAscii();
components = data.getList(SuiComponent.class);
rangeObjId = data.getLong();
maxDistance = data.getFloat();
// unk long
// unk int
}
@Override
public int getLength() {
int listSize = 0;
for (SuiComponent component : components) {
listSize += component.getLength();
}
return 34 + suiScript.length() + listSize;
}
}

View File

@@ -0,0 +1,242 @@
/***********************************************************************************
* Copyright (c) 2024 /// 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.sui
import com.projectswg.common.encoding.Encodable
import com.projectswg.common.network.NetBuffer
import me.joshlarson.jlcommon.log.Log
import java.nio.charset.StandardCharsets
open class SuiBaseWindow : Encodable {
var id: Int = 0
var suiScript: String? = null
var rangeObjId: Long = 0
var maxDistance: Float = 0f
private var components: MutableList<SuiComponent> = ArrayList()
private var callbacks: MutableMap<String, ISuiCallback>? = null
private var hasSubscriptionComponent = false
fun clearDataSource(dataSource: String) {
val component = SuiComponent(SuiComponent.Type.CLEAR_DATA_SOURCE, dataSource)
components.add(component)
}
fun addChildWidget(type: String, childWidget: String, parentWidget: String) {
val component = SuiComponent(SuiComponent.Type.ADD_CHILD_WIDGET, parentWidget)
component.addNarrowParam(type)
component.addNarrowParam(childWidget)
components.add(component)
}
fun setProperty(widget: String, property: String, value: String) {
val component = SuiComponent(SuiComponent.Type.SET_PROPERTY, widget)
component.addNarrowParam(property)
component.addWideParam(value)
components.add(component)
}
fun addDataItem(dataSource: String, name: String, value: String) {
val component = SuiComponent(SuiComponent.Type.ADD_DATA_ITEM, dataSource)
component.addNarrowParam(name)
component.addWideParam(value)
components.add(component)
}
protected fun subscribeToEvent(event: Int, widgetSource: String, callback: String) {
var component = getSubscriptionForEvent(event, widgetSource)
if (component != null) {
Log.i("Added event callback %d to %s when the event is already subscribed to, replacing callback to %s", event, widgetSource, callback)
component.setNarrowParam(1, callback) // Replaces the callback for a SUBSCRIBE_TO_EVENT component that's set 4 lines below
} else {
component = SuiComponent(SuiComponent.Type.SUBSCRIBE_TO_EVENT, widgetSource)
component.addNarrowParam(getWrappedEventString(event))
component.addNarrowParam(callback)
components.add(component)
}
if (!hasSubscriptionComponent()) hasSubscriptionComponent = true
}
protected fun subscribeToPropertyEvent(event: Int, widgetSource: String, propertyWidget: String, propertyName: String) {
var component = getSubscriptionForEvent(event, widgetSource)
if (component != null) {
// This component already has the trigger and source param, just need to add the widget and property
// for client to return the value to the server
component.addNarrowParam(propertyWidget)
component.addNarrowParam(propertyName)
} else {
component = SuiComponent(SuiComponent.Type.SUBSCRIBE_TO_EVENT, widgetSource)
component.addNarrowParam(getWrappedEventString(event))
component.addNarrowParam("")
component.addNarrowParam(propertyWidget)
component.addNarrowParam(propertyName)
components.add(component)
}
if (!hasSubscriptionComponent()) hasSubscriptionComponent = true
}
fun addDataSourceContainer(dataSourceContainer: String, name: String, value: String) {
val component = SuiComponent(SuiComponent.Type.ADD_DATA_SOURCE_CONTAINER, dataSourceContainer)
component.addNarrowParam(name)
component.addWideParam(value)
components.add(component)
}
fun clearDataSourceContainer(dataSourceContainer: String) {
val component = SuiComponent(SuiComponent.Type.CLEAR_DATA_SOURCE_CONTAINER, dataSourceContainer)
components.add(component)
}
fun addDataSource(dataSource: String, name: String, value: String) {
val component = SuiComponent(SuiComponent.Type.ADD_DATA_SOURCE, dataSource)
component.addNarrowParam(name)
component.addWideParam(value)
components.add(component)
}
fun addReturnableProperty(event: SuiEvent, source: String, widget: String, property: String) {
subscribeToPropertyEvent(event.value, source, widget, property)
}
fun addReturnableProperty(event: SuiEvent, widget: String, property: String) {
addReturnableProperty(event, "", widget, property)
}
fun addReturnableProperty(widget: String, property: String) {
subscribeToPropertyEvent(SuiEvent.OK_PRESSED.value, "", widget, property)
subscribeToPropertyEvent(SuiEvent.CANCEL_PRESSED.value, "", widget, property)
}
fun addCallback(event: SuiEvent, source: String, name: String, callback: ISuiCallback) {
subscribeToEvent(event.value, source, name)
addJavaCallback(name, callback)
}
fun addCallback(event: SuiEvent, name: String, callback: ISuiCallback) {
addCallback(event, "", name, callback)
}
fun addCallback(source: String, name: String, callback: ISuiCallback) {
subscribeToEvent(SuiEvent.OK_PRESSED.value, source, name)
subscribeToEvent(SuiEvent.CANCEL_PRESSED.value, source, name)
addJavaCallback(name, callback)
}
fun addCallback(name: String, callback: ISuiCallback) {
addCallback("", name, callback)
}
fun getSubscriptionForEvent(event: Int, widget: String): SuiComponent? {
for (component in components) {
if (component.type != SuiComponent.Type.SUBSCRIBE_TO_EVENT) continue
val eventType = component.subscribedToEventType
if (eventType == event && component.target == widget) return component
}
return null
}
fun getSubscriptionByIndex(index: Int): SuiComponent? {
var count = 0
for (component in components) {
if (component.type == SuiComponent.Type.SUBSCRIBE_TO_EVENT) {
if (index == count) return component
else count++
}
}
return null
}
fun getComponents(): List<SuiComponent> {
return components
}
fun getJavaCallback(name: String?): ISuiCallback? {
return callbacks?.get(name)
}
fun hasJavaCallback(name: String?): Boolean {
return callbacks?.containsKey(name) ?: false
}
fun hasSubscriptionComponent(): Boolean {
return hasSubscriptionComponent
}
private fun addJavaCallback(name: String, callback: ISuiCallback) {
if (callbacks == null)
callbacks = HashMap()
callbacks!![name] = callback
}
private fun getWrappedEventString(event: Int): String {
return String(byteArrayOf(event.toByte()), StandardCharsets.UTF_8)
}
override fun encode(): ByteArray {
val data = NetBuffer.allocate(length)
data.addInt(id)
data.addAscii(suiScript)
data.addList(components)
data.addLong(rangeObjId)
data.addFloat(maxDistance)
data.addLong(0) // Window Location?
data.addInt(0)
return data.array()
}
override fun decode(data: NetBuffer) {
id = data.int
suiScript = data.ascii
components = data.getList(SuiComponent::class.java)
rangeObjId = data.long
maxDistance = data.float
// unk long
// unk int
}
override val length: Int
get() {
var listSize = 0
for (component in components) {
listSize += component.length
}
return 34 + suiScript!!.length + listSize
}
}

View File

@@ -1,199 +0,0 @@
/***********************************************************************************
* Copyright (c) 2018 /// 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.sui;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import me.joshlarson.jlcommon.log.Log;
import com.projectswg.common.encoding.Encodable;
import com.projectswg.common.encoding.StringType;
import com.projectswg.common.network.NetBuffer;
/**
* @author Waverunner
*/
public class SuiComponent implements Encodable {
private Type type;
private List <String> wideParams;
private List<String> narrowParams;
public SuiComponent() {
type = Type.NONE;
wideParams = new ArrayList<>();
narrowParams = new ArrayList<>();
}
public SuiComponent(Type type, String widget) {
this.type = type;
this.wideParams = new ArrayList<>(3);
this.narrowParams = new ArrayList<>(3);
narrowParams.add(widget);
}
public Type getType() {
return type;
}
public List <String> getNarrowParams() {
return narrowParams;
}
public List <String> getWideParams() {
return wideParams;
}
/**
* Retrieve the base widget that this component targets
* @return Base widget this component targets
*/
public String getTarget() {
return narrowParams.get(0);
}
public void addNarrowParam(String param) {
narrowParams.add(param);
}
public void addWideParam(String param) {
wideParams.add(param);
}
public List<String> getSubscribedProperties() {
if (type != Type.SUBSCRIBE_TO_EVENT)
return null;
int size = narrowParams.size();
if (size < 3) {
Log.w("Tried to get subscribed properties when there are none for target %s", getTarget());
} else {
List<String> subscribedProperties = new ArrayList<>();
for (int i = 3; i < size;) {
String property = narrowParams.get(i++) + "." + narrowParams.get(i++);
subscribedProperties.add(property);
}
return subscribedProperties;
}
return null;
}
public String getSubscribeToEventCallback() {
if (type != Type.SUBSCRIBE_TO_EVENT)
return null;
int size = narrowParams.size();
if (size < 3) {
Log.w("Tried to get subscribed callback when there is none for target %s", getTarget());
} else {
return narrowParams.get(2);
}
return null;
}
public int getSubscribedToEventType() {
if (type != Type.SUBSCRIBE_TO_EVENT)
return -1;
int size = narrowParams.size();
if (size < 3) {
Log.w("Tried to get subscribed event type when there is none for target %s", getTarget());
} else {
byte[] bytes = narrowParams.get(1).getBytes(StandardCharsets.UTF_8);
if (bytes.length > 1) {
Log.w("Tried to get eventType but narrowparams string byte array length is more than 1");
return -1;
}
return bytes[0];
}
return -1;
}
@Override
public byte[] encode() {
NetBuffer data = NetBuffer.allocate(getLength());
data.addByte(type.getValue());
data.addList(wideParams, StringType.UNICODE);
data.addList(narrowParams, StringType.ASCII);
return data.array();
}
@Override
public void decode(NetBuffer data) {
type = Type.valueOf(data.getByte());
wideParams = data.getList(StringType.UNICODE);
narrowParams = data.getList(StringType.ASCII);
}
@Override
public int getLength() {
int size = 9;
for (String param : wideParams) {
size += 4 + (param.length() * 2);
}
for (String param : narrowParams) {
size += 2 + param.length();
}
return size;
}
public enum Type {
NONE(0),
CLEAR_DATA_SOURCE(1),
ADD_CHILD_WIDGET(2),
SET_PROPERTY(3),
ADD_DATA_ITEM(4),
SUBSCRIBE_TO_EVENT(5),
ADD_DATA_SOURCE_CONTAINER(6),
CLEAR_DATA_SOURCE_CONTAINER(7),
ADD_DATA_SOURCE(8);
private byte value;
Type(int value) {
this.value = (byte) value;
}
public byte getValue() {
return value;
}
public static Type valueOf(byte value) {
for (Type type : Type.values()) {
if (type.getValue() == value)
return type;
}
return NONE;
}
}
}

View File

@@ -0,0 +1,171 @@
/***********************************************************************************
* Copyright (c) 2024 /// 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.sui
import com.projectswg.common.encoding.Encodable
import com.projectswg.common.encoding.StringType
import com.projectswg.common.network.NetBuffer
import me.joshlarson.jlcommon.log.Log
import java.nio.charset.StandardCharsets
import kotlin.collections.ArrayList
class SuiComponent(type: Type, widget: String) : Encodable {
var type: Type = type
private set
private var _wideParams: MutableList<String> = ArrayList()
private var _narrowParams: MutableList<String> = ArrayList()
val target: String
/**
* Retrieve the base widget that this component targets
* @return Base widget this component targets
*/
get() = _narrowParams[0]
fun addNarrowParam(param: String) {
_narrowParams.add(param)
}
fun setNarrowParam(index: Int, param: String) {
_narrowParams[index] = param
}
fun addWideParam(param: String) {
_wideParams.add(param)
}
val subscribedProperties: List<String>?
get() {
if (type != Type.SUBSCRIBE_TO_EVENT) return null
val size = _narrowParams.size
if (size < 3) {
Log.w("Tried to get subscribed properties when there are none for target %s", target)
} else {
val subscribedProperties: MutableList<String> = ArrayList()
var i = 3
while (i < size) {
val property = _narrowParams[i++] + "." + _narrowParams[i++]
subscribedProperties.add(property)
}
return subscribedProperties
}
return null
}
val subscribeToEventCallback: String?
get() {
if (type != Type.SUBSCRIBE_TO_EVENT) return null
val size = _narrowParams.size
if (size < 3) {
Log.w("Tried to get subscribed callback when there is none for target %s", target)
} else {
return _narrowParams[2]
}
return null
}
val subscribedToEventType: Int
get() {
if (type != Type.SUBSCRIBE_TO_EVENT) return -1
val size = _narrowParams.size
if (size < 3) {
Log.w("Tried to get subscribed event type when there is none for target %s", target)
} else {
val bytes = _narrowParams[1].toByteArray(StandardCharsets.UTF_8)
if (bytes.size > 1) {
Log.w("Tried to get eventType but narrowparams string byte array length is more than 1")
return -1
}
return bytes[0].toInt()
}
return -1
}
override fun encode(): ByteArray {
val data = NetBuffer.allocate(length)
data.addByte(type.value.toInt())
data.addList(_wideParams, StringType.UNICODE)
data.addList(_narrowParams, StringType.ASCII)
return data.array()
}
override fun decode(data: NetBuffer) {
type = Type.valueOf(data.byte)
_wideParams = data.getList(StringType.UNICODE)
_narrowParams = data.getList(StringType.ASCII)
}
override val length: Int
get() {
var size = 9
for (param in _wideParams) {
size += 4 + (param.length * 2)
}
for (param in _narrowParams) {
size += 2 + param.length
}
return size
}
enum class Type(value: Int) {
NONE(0),
CLEAR_DATA_SOURCE(1),
ADD_CHILD_WIDGET(2),
SET_PROPERTY(3),
ADD_DATA_ITEM(4),
SUBSCRIBE_TO_EVENT(5),
ADD_DATA_SOURCE_CONTAINER(6),
CLEAR_DATA_SOURCE_CONTAINER(7),
ADD_DATA_SOURCE(8);
val value: Byte = value.toByte()
companion object {
fun valueOf(value: Byte): Type {
for (type in entries) {
if (type.value == value) return type
}
return NONE
}
}
}
init {
this._wideParams = ArrayList(3)
this._narrowParams = ArrayList(3)
_narrowParams.add(widget)
}
}

View File

@@ -1,5 +1,5 @@
/***********************************************************************************
* Copyright (c) 2018 /// Project SWG /// www.projectswg.com *
* Copyright (c) 2024 /// 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. *
@@ -24,48 +24,37 @@
* 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.sui;
package com.projectswg.common.data.sui
/**
* Created by Waverunner on 8/14/2015
*/
public enum SuiEvent {
NONE (0),
BUTTON (1),
CHECKBOX (2),
ENABLE_DISABLE (3),
GENERIC (4),
SLIDER (5),
TAB_PANE (6),
TEXTBOX (7),
VISIBILITY_CHANGED (8),
OK_PRESSED (9),
CANCEL_PRESSED (10);
private int value;
SuiEvent(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static SuiEvent valueOf(int value) {
switch(value) {
case 0: return NONE;
case 1: return BUTTON;
case 2: return CHECKBOX;
case 3: return ENABLE_DISABLE;
case 4: return GENERIC;
case 5: return SLIDER;
case 6: return TAB_PANE;
case 7: return TEXTBOX;
case 8: return VISIBILITY_CHANGED;
case 9: return OK_PRESSED;
case 10: return CANCEL_PRESSED;
default: return NONE;
enum class SuiEvent(val value: Int) {
NONE(0),
BUTTON(1),
CHECKBOX(2),
ENABLE_DISABLE(3),
GENERIC(4),
SLIDER(5),
TAB_PANE(6),
TEXTBOX(7),
VISIBILITY_CHANGED(8),
OK_PRESSED(9),
CANCEL_PRESSED(10);
companion object {
fun valueOf(value: Int): SuiEvent {
return when (value) {
0 -> NONE
1 -> BUTTON
2 -> CHECKBOX
3 -> ENABLE_DISABLE
4 -> GENERIC
5 -> SLIDER
6 -> TAB_PANE
7 -> TEXTBOX
8 -> VISIBILITY_CHANGED
9 -> OK_PRESSED
10 -> CANCEL_PRESSED
else -> NONE
}
}
}
}