Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-03 14:50:30 +01:00
Add method to get Protocol by supported versions, some cleanup
Dieser Commit ist enthalten in:
Ursprung
ff140c421a
Commit
3618914ce9
@ -53,6 +53,28 @@ public interface ProtocolManager {
|
|||||||
*/
|
*/
|
||||||
@Nullable <T extends Protocol> T getProtocol(Class<T> protocolClass);
|
@Nullable <T extends Protocol> T getProtocol(Class<T> protocolClass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a protocol transforming packets for server version to the given client version.
|
||||||
|
*
|
||||||
|
* @param clientVersion client protocol version
|
||||||
|
* @param serverVersion server protocol version
|
||||||
|
* @return protocol if present, else null
|
||||||
|
* @see #getProtocolPath(int, int) to get a full path of Protocols between a larger gap of versions
|
||||||
|
*/
|
||||||
|
default @Nullable Protocol getProtocol(ProtocolVersion clientVersion, ProtocolVersion serverVersion) {
|
||||||
|
return getProtocol(clientVersion.getVersion(), serverVersion.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a protocol transforming packets for server version to the given client version.
|
||||||
|
*
|
||||||
|
* @param clientVersion client protocol version
|
||||||
|
* @param serverVersion server protocol version
|
||||||
|
* @return protocol if present, else null
|
||||||
|
* @see #getProtocolPath(int, int) to get a full path of Protocols between a larger gap of versions
|
||||||
|
*/
|
||||||
|
@Nullable Protocol getProtocol(int clientVersion, int serverVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the base protocol handling serverbound handshake packets.
|
* Returns the base protocol handling serverbound handshake packets.
|
||||||
*
|
*
|
||||||
@ -84,37 +106,37 @@ public interface ProtocolManager {
|
|||||||
/**
|
/**
|
||||||
* Register a protocol.
|
* Register a protocol.
|
||||||
*
|
*
|
||||||
* @param protocol protocol to register
|
* @param protocol protocol to register
|
||||||
* @param supported supported client versions
|
* @param clientVersion supported client protocol versions
|
||||||
* @param output output server version the protocol converts to
|
* @param serverVersion output server protocol version the protocol converts to
|
||||||
*/
|
*/
|
||||||
void registerProtocol(Protocol protocol, ProtocolVersion supported, ProtocolVersion output);
|
void registerProtocol(Protocol protocol, ProtocolVersion clientVersion, ProtocolVersion serverVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a protocol.
|
* Register a protocol.
|
||||||
*
|
*
|
||||||
* @param protocol protocol to register
|
* @param protocol protocol to register
|
||||||
* @param supported supported client versions
|
* @param supportedClientVersion supported client protocol versions
|
||||||
* @param output output server version the protocol converts to
|
* @param serverVersion output server protocol version the protocol converts to
|
||||||
*/
|
*/
|
||||||
void registerProtocol(Protocol protocol, List<Integer> supported, int output);
|
void registerProtocol(Protocol protocol, List<Integer> supportedClientVersion, int serverVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a base protocol. Base Protocols registered later have higher priority.
|
* Registers a base protocol. Base Protocols registered later have higher priority.
|
||||||
* Only base protocol will always be added to pipeline.
|
* Only base protocol will always be added to pipeline.
|
||||||
*
|
*
|
||||||
* @param baseProtocol base protocol to register
|
* @param baseProtocol base protocol to register
|
||||||
* @param supportedProtocols versions supported by the base protocol
|
* @param supportedProtocols protocol versions supported by the base protocol
|
||||||
* @throws IllegalArgumentException if the protocol is not a base protocol as given by {@link Protocol#isBaseProtocol()}
|
* @throws IllegalArgumentException if the protocol is not a base protocol as given by {@link Protocol#isBaseProtocol()}
|
||||||
*/
|
*/
|
||||||
void registerBaseProtocol(Protocol baseProtocol, Range<Integer> supportedProtocols);
|
void registerBaseProtocol(Protocol baseProtocol, Range<Integer> supportedProtocols);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates and returns the protocol path from a client version to server version.
|
* Calculates and returns the protocol path from a client protocol version to server protocol version.
|
||||||
* Returns null if no path could be found or the path length exceeds the value given by {@link #getMaxProtocolPathSize()}.
|
* Returns null if no path could be found or the path length exceeds the value given by {@link #getMaxProtocolPathSize()}.
|
||||||
*
|
*
|
||||||
* @param clientVersion input client version
|
* @param clientVersion input client protocol version
|
||||||
* @param serverVersion desired output server version
|
* @param serverVersion desired output server protocol version
|
||||||
* @return path generated, or null if not supported or the length exceeds {@link #getMaxProtocolPathSize()}
|
* @return path generated, or null if not supported or the length exceeds {@link #getMaxProtocolPathSize()}
|
||||||
*/
|
*/
|
||||||
@Nullable List<ProtocolPathEntry> getProtocolPath(int clientVersion, int serverVersion);
|
@Nullable List<ProtocolPathEntry> getProtocolPath(int clientVersion, int serverVersion);
|
||||||
@ -135,9 +157,9 @@ public interface ProtocolManager {
|
|||||||
void setMaxProtocolPathSize(int maxProtocolPathSize);
|
void setMaxProtocolPathSize(int maxProtocolPathSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the versions compatible with the server.
|
* Returns the protocol versions compatible with the server.
|
||||||
*
|
*
|
||||||
* @return sorted, immutable set of supported versions
|
* @return sorted, immutable set of supported protocol versions
|
||||||
*/
|
*/
|
||||||
SortedSet<Integer> getSupportedVersions();
|
SortedSet<Integer> getSupportedVersions();
|
||||||
|
|
||||||
|
@ -26,11 +26,12 @@ import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
|||||||
import com.viaversion.viaversion.api.type.Type;
|
import com.viaversion.viaversion.api.type.Type;
|
||||||
|
|
||||||
public abstract class BaseChunkType extends Type<Chunk> {
|
public abstract class BaseChunkType extends Type<Chunk> {
|
||||||
public BaseChunkType() {
|
|
||||||
|
protected BaseChunkType() {
|
||||||
super(Chunk.class);
|
super(Chunk.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseChunkType(String typeName) {
|
protected BaseChunkType(String typeName) {
|
||||||
super(typeName, Chunk.class);
|
super(typeName, Chunk.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,11 +26,12 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
|
|||||||
import com.viaversion.viaversion.api.type.Type;
|
import com.viaversion.viaversion.api.type.Type;
|
||||||
|
|
||||||
public abstract class BaseItemArrayType extends Type<Item[]> {
|
public abstract class BaseItemArrayType extends Type<Item[]> {
|
||||||
public BaseItemArrayType() {
|
|
||||||
|
protected BaseItemArrayType() {
|
||||||
super(Item[].class);
|
super(Item[].class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseItemArrayType(String typeName) {
|
protected BaseItemArrayType(String typeName) {
|
||||||
super(typeName, Item[].class);
|
super(typeName, Item[].class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,11 +26,12 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
|
|||||||
import com.viaversion.viaversion.api.type.Type;
|
import com.viaversion.viaversion.api.type.Type;
|
||||||
|
|
||||||
public abstract class BaseItemType extends Type<Item> {
|
public abstract class BaseItemType extends Type<Item> {
|
||||||
public BaseItemType() {
|
|
||||||
|
protected BaseItemType() {
|
||||||
super(Item.class);
|
super(Item.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseItemType(String typeName) {
|
protected BaseItemType(String typeName) {
|
||||||
super(typeName, Item.class);
|
super(typeName, Item.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,12 +160,12 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerProtocol(Protocol protocol, ProtocolVersion supported, ProtocolVersion output) {
|
public void registerProtocol(Protocol protocol, ProtocolVersion clientVersion, ProtocolVersion serverVersion) {
|
||||||
registerProtocol(protocol, Collections.singletonList(supported.getVersion()), output.getVersion());
|
registerProtocol(protocol, Collections.singletonList(clientVersion.getVersion()), serverVersion.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerProtocol(Protocol protocol, List<Integer> supported, int output) {
|
public void registerProtocol(Protocol protocol, List<Integer> supportedClientVersion, int serverVersion) {
|
||||||
// Clear cache as this may make new routes.
|
// Clear cache as this may make new routes.
|
||||||
if (!pathCache.isEmpty()) {
|
if (!pathCache.isEmpty()) {
|
||||||
pathCache.clear();
|
pathCache.clear();
|
||||||
@ -173,9 +173,9 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
|||||||
|
|
||||||
protocols.put(protocol.getClass(), protocol);
|
protocols.put(protocol.getClass(), protocol);
|
||||||
|
|
||||||
for (int version : supported) {
|
for (int version : supportedClientVersion) {
|
||||||
Int2ObjectMap<Protocol> protocolMap = registryMap.computeIfAbsent(version, s -> new Int2ObjectOpenHashMap<>(2));
|
Int2ObjectMap<Protocol> protocolMap = registryMap.computeIfAbsent(version, s -> new Int2ObjectOpenHashMap<>(2));
|
||||||
protocolMap.put(output, protocol);
|
protocolMap.put(serverVersion, protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Via.getPlatform().isPluginEnabled()) {
|
if (Via.getPlatform().isPluginEnabled()) {
|
||||||
@ -249,6 +249,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
|||||||
* @return path that has been generated, null if failed
|
* @return path that has been generated, null if failed
|
||||||
*/
|
*/
|
||||||
private @Nullable List<ProtocolPathEntry> getProtocolPath(List<ProtocolPathEntry> current, int clientVersion, int serverVersion) {
|
private @Nullable List<ProtocolPathEntry> getProtocolPath(List<ProtocolPathEntry> current, int clientVersion, int serverVersion) {
|
||||||
|
//TODO optimize?
|
||||||
if (clientVersion == serverVersion) return null; // We're already there
|
if (clientVersion == serverVersion) return null; // We're already there
|
||||||
if (current.size() > maxProtocolPathSize) return null; // Fail safe, protocol too complicated.
|
if (current.size() > maxProtocolPathSize) return null; // Fail safe, protocol too complicated.
|
||||||
|
|
||||||
@ -297,6 +298,12 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
|||||||
return (T) protocols.get(protocolClass);
|
return (T) protocols.get(protocolClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Protocol getProtocol(int clientVersion, int serverVersion) {
|
||||||
|
Int2ObjectMap<Protocol> map = registryMap.get(clientVersion);
|
||||||
|
return map != null ? map.get(serverVersion) : null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Protocol getBaseProtocol(int serverVersion) {
|
public Protocol getBaseProtocol(int serverVersion) {
|
||||||
for (Pair<Range<Integer>, Protocol> rangeProtocol : Lists.reverse(baseProtocols)) {
|
for (Pair<Range<Integer>, Protocol> rangeProtocol : Lists.reverse(baseProtocols)) {
|
||||||
|
@ -63,12 +63,11 @@ public class PacketWrapperImpl implements PacketWrapper {
|
|||||||
public <T> T get(Type<T> type, int index) throws Exception {
|
public <T> T get(Type<T> type, int index) throws Exception {
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
for (Pair<Type, Object> packetValue : packetValues) {
|
for (Pair<Type, Object> packetValue : packetValues) {
|
||||||
if (packetValue.getKey() == type) { // Ref check
|
if (packetValue.getKey() != type) continue;
|
||||||
if (currentIndex == index) {
|
if (currentIndex == index) {
|
||||||
return (T) packetValue.getValue();
|
return (T) packetValue.getValue();
|
||||||
}
|
|
||||||
currentIndex++;
|
|
||||||
}
|
}
|
||||||
|
currentIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Exception e = new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index);
|
Exception e = new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index);
|
||||||
@ -79,12 +78,11 @@ public class PacketWrapperImpl implements PacketWrapper {
|
|||||||
public boolean is(Type type, int index) {
|
public boolean is(Type type, int index) {
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
for (Pair<Type, Object> packetValue : packetValues) {
|
for (Pair<Type, Object> packetValue : packetValues) {
|
||||||
if (packetValue.getKey() == type) { // Ref check
|
if (packetValue.getKey() != type) continue;
|
||||||
if (currentIndex == index) {
|
if (currentIndex == index) {
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
currentIndex++;
|
|
||||||
}
|
}
|
||||||
|
currentIndex++;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -93,12 +91,11 @@ public class PacketWrapperImpl implements PacketWrapper {
|
|||||||
public boolean isReadable(Type type, int index) {
|
public boolean isReadable(Type type, int index) {
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
for (Pair<Type, Object> packetValue : readableObjects) {
|
for (Pair<Type, Object> packetValue : readableObjects) {
|
||||||
if (packetValue.getKey().getBaseClass() == type.getBaseClass()) { // Ref check
|
if (packetValue.getKey().getBaseClass() != type.getBaseClass()) continue;
|
||||||
if (currentIndex == index) {
|
if (currentIndex == index) {
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
currentIndex++;
|
|
||||||
}
|
}
|
||||||
|
currentIndex++;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -108,13 +105,12 @@ public class PacketWrapperImpl implements PacketWrapper {
|
|||||||
public <T> void set(Type<T> type, int index, T value) throws Exception {
|
public <T> void set(Type<T> type, int index, T value) throws Exception {
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
for (Pair<Type, Object> packetValue : packetValues) {
|
for (Pair<Type, Object> packetValue : packetValues) {
|
||||||
if (packetValue.getKey() == type) { // Ref check
|
if (packetValue.getKey() != type) continue;
|
||||||
if (currentIndex == index) {
|
if (currentIndex == index) {
|
||||||
packetValue.setValue(value);
|
packetValue.setValue(attemptTransform(type, value));
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
currentIndex++;
|
|
||||||
}
|
}
|
||||||
|
currentIndex++;
|
||||||
}
|
}
|
||||||
Exception e = new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index);
|
Exception e = new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index);
|
||||||
throw new InformativeException(e).set("Type", type.getTypeName()).set("Index", index).set("Packet ID", getId());
|
throw new InformativeException(e).set("Type", type.getTypeName()).set("Index", index).set("Packet ID", getId());
|
||||||
@ -131,37 +127,44 @@ public class PacketWrapperImpl implements PacketWrapper {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new InformativeException(e).set("Type", type.getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
|
throw new InformativeException(e).set("Type", type.getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<Type, Object> read = readableObjects.poll();
|
||||||
|
Type rtype = read.getKey();
|
||||||
|
if (rtype == type
|
||||||
|
|| (type.getBaseClass() == rtype.getBaseClass()
|
||||||
|
&& type.getOutputClass() == rtype.getOutputClass())) {
|
||||||
|
return (T) read.getValue();
|
||||||
|
} else if (rtype == Type.NOTHING) {
|
||||||
|
return read(type); // retry
|
||||||
} else {
|
} else {
|
||||||
Pair<Type, Object> read = readableObjects.poll();
|
Exception e = new IOException("Unable to read type " + type.getTypeName() + ", found " + read.getKey().getTypeName());
|
||||||
Type rtype = read.getKey();
|
throw new InformativeException(e).set("Type", type.getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
|
||||||
if (rtype.equals(type)
|
|
||||||
|| (type.getBaseClass().equals(rtype.getBaseClass())
|
|
||||||
&& type.getOutputClass().equals(rtype.getOutputClass()))) {
|
|
||||||
return (T) read.getValue();
|
|
||||||
} else {
|
|
||||||
if (rtype == Type.NOTHING) {
|
|
||||||
return read(type); // retry
|
|
||||||
} else {
|
|
||||||
Exception e = new IOException("Unable to read type " + type.getTypeName() + ", found " + read.getKey().getTypeName());
|
|
||||||
throw new InformativeException(e).set("Type", type.getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> void write(Type<T> type, T value) {
|
public <T> void write(Type<T> type, T value) {
|
||||||
if (value != null) {
|
packetValues.add(new Pair<>(type, attemptTransform(type, value)));
|
||||||
if (!type.getOutputClass().isAssignableFrom(value.getClass())) {
|
}
|
||||||
// attempt conversion
|
|
||||||
if (type instanceof TypeConverter) {
|
/**
|
||||||
value = (T) ((TypeConverter) type).from(value);
|
* Returns the value if already matching, else the converted value or possibly unmatched value.
|
||||||
} else {
|
*
|
||||||
Via.getPlatform().getLogger().warning("Possible type mismatch: " + value.getClass().getName() + " -> " + type.getOutputClass());
|
* @param expectedType expected type
|
||||||
}
|
* @param value value
|
||||||
|
* @return value if already matching, else the converted value or possibly unmatched value
|
||||||
|
*/
|
||||||
|
private @Nullable Object attemptTransform(Type<?> expectedType, @Nullable Object value) {
|
||||||
|
if (value != null && !expectedType.getOutputClass().isAssignableFrom(value.getClass())) {
|
||||||
|
// Attempt conversion
|
||||||
|
if (expectedType instanceof TypeConverter) {
|
||||||
|
return ((TypeConverter) expectedType).from(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Via.getPlatform().getLogger().warning("Possible type mismatch: " + value.getClass().getName() + " -> " + expectedType.getOutputClass());
|
||||||
}
|
}
|
||||||
packetValues.add(new Pair<>(type, value));
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -195,18 +198,7 @@ public class PacketWrapperImpl implements PacketWrapper {
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
for (Pair<Type, Object> packetValue : packetValues) {
|
for (Pair<Type, Object> packetValue : packetValues) {
|
||||||
try {
|
try {
|
||||||
Object value = packetValue.getValue();
|
packetValue.getKey().write(buffer, packetValue.getValue());
|
||||||
if (value != null) {
|
|
||||||
if (!packetValue.getKey().getOutputClass().isAssignableFrom(value.getClass())) {
|
|
||||||
// attempt conversion
|
|
||||||
if (packetValue.getKey() instanceof TypeConverter) {
|
|
||||||
value = ((TypeConverter) packetValue.getKey()).from(value);
|
|
||||||
} else {
|
|
||||||
Via.getPlatform().getLogger().warning("Possible type mismatch: " + value.getClass().getName() + " -> " + packetValue.getKey().getOutputClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
packetValue.getKey().write(buffer, value);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new InformativeException(e).set("Index", index).set("Type", packetValue.getKey().getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
|
throw new InformativeException(e).set("Index", index).set("Type", packetValue.getKey().getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
|
||||||
}
|
}
|
||||||
@ -428,8 +420,7 @@ public class PacketWrapperImpl implements PacketWrapper {
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public @Nullable ByteBuf getInputBuffer() {
|
||||||
public ByteBuf getInputBuffer() {
|
|
||||||
return inputBuffer;
|
return inputBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,13 +55,14 @@ public class BaseProtocol extends AbstractSimpleProtocol {
|
|||||||
ProtocolInfo info = wrapper.user().getProtocolInfo();
|
ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||||
info.setProtocolVersion(protocolVersion);
|
info.setProtocolVersion(protocolVersion);
|
||||||
// Ensure the server has a version provider
|
// Ensure the server has a version provider
|
||||||
if (Via.getManager().getProviders().get(VersionProvider.class) == null) {
|
VersionProvider versionProvider = Via.getManager().getProviders().get(VersionProvider.class);
|
||||||
|
if (versionProvider == null) {
|
||||||
wrapper.user().setActive(false);
|
wrapper.user().setActive(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose the pipe
|
// Choose the pipe
|
||||||
int serverProtocol = Via.getManager().getProviders().get(VersionProvider.class).getClosestServerProtocol(wrapper.user());
|
int serverProtocol = versionProvider.getClosestServerProtocol(wrapper.user());
|
||||||
info.setServerProtocolVersion(serverProtocol);
|
info.setServerProtocolVersion(serverProtocol);
|
||||||
List<ProtocolPathEntry> protocolPath = null;
|
List<ProtocolPathEntry> protocolPath = null;
|
||||||
|
|
||||||
@ -94,8 +95,7 @@ public class BaseProtocol extends AbstractSimpleProtocol {
|
|||||||
// Change state
|
// Change state
|
||||||
if (state == 1) {
|
if (state == 1) {
|
||||||
info.setState(State.STATUS);
|
info.setState(State.STATUS);
|
||||||
}
|
} else if (state == 2) {
|
||||||
if (state == 2) {
|
|
||||||
info.setState(State.LOGIN);
|
info.setState(State.LOGIN);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren