Skip to content

Instantly share code, notes, and snippets.

@Mr00Anderson
Created December 13, 2020 12:25
Show Gist options
  • Save Mr00Anderson/e074ddd5f3e56f5c5e973b0ac8f7615e to your computer and use it in GitHub Desktop.
Save Mr00Anderson/e074ddd5f3e56f5c5e973b0ac8f7615e to your computer and use it in GitHub Desktop.
Account client
package app.virtualhex.network.clients;
import app.virtualhex.gdx.engine.state.StateReference;
import app.virtualhex.math.VLQUtilsNative;
import app.virtualhex.network.PacketManager;
import app.virtualhex.network.RawWebSocketsSession;
import app.virtualhex.network.RawWebSocketsSessionFactory;
import com.badlogic.gdx.Gdx;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.concurrent.*;
// Will automatically connect and get account token if user logging on
/**
* Life cycle
* Connect (Set email or Resume Session)
* Verify Code
*
* - SetRegistration
* - Invalidate
*/
public class AccountClient extends AccountPacket {
public final ScheduledExecutorService executor;
public final RawWebSocketsSessionFactory sessionBackend;
public final RawWebSocketsSession session;
private final StateReference stateRef;
public ClientState clientState;
public Object msgObject;
public AccountClient(ScheduledExecutorService executor, String address, int port, RawWebSocketsSessionFactory sessionBackend, StateReference stateRef) throws InterruptedException, UnknownHostException, URISyntaxException {
this.executor = executor;
this.sessionBackend = sessionBackend;
this.stateRef = stateRef;
this.session = sessionBackend.generate(address, port, "accounting");
Boolean rememberSession = stateRef.getOrDefault("rememberSession", false);
if(!rememberSession) {
clientState = ClientState.SET_EMAIL;
return;
}
String email = stateRef.getOrDefault("email", "");
String token = stateRef.getOrDefault("token", "");
if(email == null || email.isEmpty() || token == null || token.isEmpty()){
clientState = ClientState.SET_EMAIL;
return;
}
clientState = ClientState.LOADING;
resumeSession(email, token);
}
public AccountClient setRegistration(String username) {
session.setSessionObject("username", username);
int emailLength = username.length();
int stringLengthFieldLength = VLQUtilsNative.computeUInt32Size(emailLength);
ByteBuffer out = ByteBuffer.allocate(1 + 1 + stringLengthFieldLength + emailLength);
out.put(AccountPacket.PACKET_ID);
out.put((byte) ClientRequest.SET_REGISTRATION.ordinal());
VLQUtilsNative.encode(out, username);
out.rewind();
session.writeBinaryFrame(out);
return this;
}
public AccountClient setEmail(String email){
session.setSessionObject("email", email);
int emailLength = email.length();
int stringLengthFieldLength = VLQUtilsNative.computeUInt32Size(emailLength);
ByteBuffer out = ByteBuffer.allocate(1 + 1 + stringLengthFieldLength + emailLength);
out.put(AccountPacket.PACKET_ID);
out.put((byte) ClientRequest.SET_EMAIL.ordinal());
VLQUtilsNative.encode(out, email);
out.rewind();
session.writeBinaryFrame(out);
return this;
}
public AccountClient setLoginCode(String loginCode){
session.setSessionObject("loginCode", loginCode);
int loginCodeLength = loginCode.length();
int stringLengthFieldLength = VLQUtilsNative.computeUInt32Size(loginCodeLength);
ByteBuffer out = ByteBuffer.allocate(1 + 1 + stringLengthFieldLength + loginCodeLength);
out.put(AccountPacket.PACKET_ID);
out.put((byte) ClientRequest.SET_LOGIN_CODE.ordinal());
VLQUtilsNative.encode(out, loginCode);
out.rewind();
session.writeBinaryFrame(out);
return this;
}
public AccountClient invalidateSession(String email, String token){
session.setSessionObject("email", "");
session.setSessionObject("token", "");
stateRef.setValue("email", "", 0);
stateRef.setValue("token", "", 0);
int emailLength = email.length();
int emailFieldLength = VLQUtilsNative.computeUInt32Size(emailLength);
int tokenLength = token.length();
int tokenFieldLength = VLQUtilsNative.computeUInt32Size(tokenLength);
ByteBuffer out = ByteBuffer.allocate(1 + 1 + emailFieldLength + emailLength + tokenFieldLength + tokenLength);
out.put(AccountPacket.PACKET_ID);
out.put((byte) ClientRequest.INVALIDATE_SESSION_TOKEN.ordinal());
VLQUtilsNative.encode(out, email);
VLQUtilsNative.encode(out, token);
out.rewind();
session.writeBinaryFrame(out);
return this;
}
public AccountClient resumeSession(String email, String token){
session.setSessionObject("email", email);
session.setSessionObject("token", token);
int emailLength = email.length();
int emailFieldLength = VLQUtilsNative.computeUInt32Size(emailLength);
int tokenLength = token.length();
int tokenFieldLength = VLQUtilsNative.computeUInt32Size(tokenLength);
ByteBuffer out = ByteBuffer.allocate(1 + 1 + emailFieldLength + emailLength + tokenFieldLength + tokenLength);
out.put(AccountPacket.PACKET_ID);
out.put((byte) ClientRequest.RESUME_SESSION.ordinal());
VLQUtilsNative.encode(out, email);
VLQUtilsNative.encode(out, token);
out.rewind();
session.writeBinaryFrame(out);
return this;
}
public void registerPacketManager(PacketManager packetManager) {
packetManager.addPacket(this);
}
@Override
public void read(RawWebSocketsSession session, ByteBuffer in) {
if(in.remaining() == 0) return;
byte requestId = in.get();
ClientState[] values = ClientState.values();
if(requestId > values.length){
Gdx.app.error("AccountClient", "received packets out of bounds from server, request id: " + requestId);
} else {
clientState = values[requestId];
if (clientState == ClientState.SESSION_TOKEN) {//TODO Cache if option or ask preference
String sessionToken = VLQUtilsNative.decodeString(in);
msgObject = sessionToken;
}
}
}
}
package app.virtualhex.network.clients;
import app.virtualhex.network.packets.AbstractPacket;
public abstract class AccountPacket extends AbstractPacket {
public static final byte PACKET_ID = 30;
public static final String NAME = "Account";
public AccountPacket() {
super(PACKET_ID, NAME);
}
// public enum Request {
// LOGIN_REQUEST, // Check to see if they have logged in before or not, not ask for information, else send code
// REGISTER,
// REGISTER_REPLY,
// REGISTER_FULL,
// REGISTER_UPDATE, // Had invalid fields, partial update
//
// }
public enum ClientState {
RESUME_SESSION,
NOT_VALID_TOKEN,
USERNAME_EXCEED_LENGTH_OR_SHORT,
LOADING,
ERROR_ISSUING_TOKEN,
SET_EMAIL,
USERNAME_NOT_AVAILABLE,
SET_LOGIN_CODE,
SESSION_TOKEN,
SET_USERNAME,
INVALID_EMAIL_OR_CODE,
INVALID_EMAIL,
INVALID_USERNAME,
INVALID_CODE,
}
public enum ClientRequest {
RESUME_SESSION,
SET_EMAIL,
SET_LOGIN_CODE,
SET_REGISTRATION,
INVALIDATE_SESSION_TOKEN,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment