Finnished ClientMsgDecoder!

last thing todo is implement
the execution of the input.
This commit is contained in:
Sebastian Lenzlinger 2022-03-26 13:14:36 +01:00
parent 9b1faa6ce1
commit b2d725f4c3
12 changed files with 423 additions and 312 deletions

View File

@ -41,7 +41,7 @@
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.009s</div>
<div class="counter">0.013s</div>
<p>duration</p>
</div>
</td>
@ -76,7 +76,7 @@
</thead>
<tr>
<td class="success">testMain()</td>
<td class="success">0.009s</td>
<td class="success">0.013s</td>
<td class="success">passed</td>
</tr>
</table>
@ -89,7 +89,7 @@
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 6.9.2</a> at 06.03.2022, 13:30:14</p>
<a href="http://www.gradle.org">Gradle 6.9.2</a> at 26.03.2022, 12:19:23</p>
</div>
</div>
</body>

View File

@ -60,31 +60,33 @@ public class Client {
}
/**
* Uses <code>NTtBProtocolParser</code> to turn Client
* input into the NTtB Protocol format.
* Must be called before a client input is sent to the server.
* Uses <code>NTtBProtocolParser</code> to turn Client input into the NTtB Protocol format. Must
* be called before a client input is sent to the server.
*
* @param msg the msg to be encoded.
* @return Message encoded adhering to the NTtB Protocoll.
*/
private String encodeMessage(String msg) throws NoLegalProtocolCommandStringFoundException, EmptyClientInputException {
private String encodeMessage(String msg)
throws NoLegalProtocolCommandStringFoundException, EmptyClientInputException {
NTtBProtocolParser pp = new NTtBProtocolParser(this);
return pp.parseMsg(msg);
}
//TODO implement decoding of server input
private String decodeServerMsg(String msg){return null;}
/**
* Listens for incoming messages
*/
public void chatListener() {
/*TODO: what type of decoding has to be done
think better about structure for incoming messages
TODO how shall input be logged?
*/
//TODO how shall input be logged?
new Thread(new Runnable() {
@Override
public void run() {
String chatMsg;
while(socket.isConnected()) {
while (socket.isConnected()) {
try {
chatMsg = in.readLine();
System.out.println(chatMsg);

View File

@ -6,11 +6,11 @@ import java.util.ArrayList;
import java.util.Scanner;
/**
* Implements a protocol parser for the NTtB protocoll,
* that transforms client input
* into a server readable format.
* Implements a protocol parser for the NTtB protocoll, that transforms client input into a server
* readable format.
*/
public class NTtBProtocolParser implements ProtocolParser {
//TODO Possibly bad name, rename to clientMsgParser?
public final Client caller;
public static InputToProtocolMap legalCommands = new InputToProtocolMap();
@ -19,13 +19,15 @@ public class NTtBProtocolParser implements ProtocolParser {
public NTtBProtocolParser(Client caller) {
this.caller = caller;
}
@Override
public String parseMsg(String msg) throws NoLegalProtocolCommandStringFoundException, EmptyClientInputException{
public String parseMsg(String msg)
throws NoLegalProtocolCommandStringFoundException, EmptyClientInputException {
Scanner sc = new Scanner(msg);
ArrayList<String> input = new ArrayList<>();
String parsedMsg = buildProtocolMsg(input);
while(sc.hasNext()){
while (sc.hasNext()) {
input.add(sc.next());
}
@ -33,16 +35,17 @@ public class NTtBProtocolParser implements ProtocolParser {
}
private String buildProtocolMsg(ArrayList<String> input) throws EmptyClientInputException, NoLegalProtocolCommandStringFoundException {
private String buildProtocolMsg(ArrayList<String> input)
throws EmptyClientInputException, NoLegalProtocolCommandStringFoundException {
//TODO
if(emptyClientInput(input)){
if (emptyClientInput(input)) {
throw new EmptyClientInputException(caller);
}
StringBuilder s = new StringBuilder(); //friendly little helper
s.append(legalCommands.encode(input.get(0)));
if (containsParameters(input)) {
int size = input.size();
for(int i = 1; i < size; i++) {
for (int i = 1; i < size; i++) {
s.append("$");
s.append(input.get(i).toLowerCase()); //parameters are always lower case (is that good?)
}
@ -52,10 +55,8 @@ public class NTtBProtocolParser implements ProtocolParser {
/**
* Checks if input has parameters
*
* if the list size is smaller than 2, i.e.
* not larger than 1, the input only contains
* a command.
* <p>
* if the list size is smaller than 2, i.e. not larger than 1, the input only contains a command.
*
* @param input the tokenized input string.
* @return true if input list is larger than 2.
@ -66,6 +67,7 @@ public class NTtBProtocolParser implements ProtocolParser {
/**
* checks if client input is empty
*
* @param clientInput the clients input.
* @return true if client didn't send any input besides whitespace
*/

View File

@ -1,9 +1,10 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.client;
public interface ProtocolParser {
/**
* Takes a String from client input and parses into
* server readable message.
* Takes a String from client input and parses into server readable message.
*
* @param msg the message to be parsed
* @return a String message formatted for the specific protocol
*/

View File

@ -4,21 +4,19 @@ import java.util.LinkedList;
import java.util.Queue;
/**
* This class defines what type the ClientMsgDecoder returns after decoding the message.
* This is done so the output can be split into a response to the client and action
* in to the game logik.
* commands should map to methods(maybe classes)
* parameters map to method parameters
*
* This class defines what type the ClientMsgDecoder returns after decoding the message. This is
* done so the output can be split into a response to the client and action in to the game logik.
* commands should map to methods(maybe classes) parameters map to method parameters
*/
public class NTtBFormatMsg {
private String msgToClient;
private NightTrainProtocol.NTtBCommands command;
private final Queue<String> parameters; //TODO maybe use array?
private final String[] parameters; //TODO maybe use array?
public NTtBFormatMsg(String msgToClient, NightTrainProtocol.NTtBCommands command, Queue<String> parameters) {
public NTtBFormatMsg(String msgToClient, NightTrainProtocol.NTtBCommands command,
String[] parameters) {
this.msgToClient = msgToClient;
this.command = command;
this.parameters = parameters;
@ -27,7 +25,7 @@ public class NTtBFormatMsg {
public NTtBFormatMsg() {
this.msgToClient = "";
this.command = null;
this.parameters = new LinkedList<>();
this.parameters = new String[]{""};
}
public String getMessage() {
@ -38,15 +36,15 @@ public class NTtBFormatMsg {
return command;
}
public Queue<String> getParameters() {
public String[] getParameters() {
return parameters;
}
public void setMsgToClient(String msgToClient) {
protected void setMsgToClient(String msgToClient) {
this.msgToClient = msgToClient;
}
public void setCommand(NightTrainProtocol.NTtBCommands command) {
protected void setCommand(NightTrainProtocol.NTtBCommands command) {
this.command = command;
}
}

View File

@ -10,9 +10,11 @@
* VOTEH: humans voting whos the ghost
* QUITS: quit server/ leave servr
* LISTP: list players/clients in session with the Server
* CPING: Ping from client to server.
*/
/**
Server Commands:
* MSGRS: "Message recieved": Paramaters: a string detailing to the client that and what the server recieved as command.
* SEROR: Server had an error. (used for debugging)
* SPING: Ping from server to client;
*/

View File

@ -19,9 +19,9 @@ public class NightTrainProtocol {
public enum NTtBCommands {
//Client Commands
CRTGM, CHATA, CHATW, CHATG, LEAVG, JOING, VOTEG, QUITS, LISTP, CUSRN,
CRTGM, CHATA, CHATW, CHATG, LEAVG, JOING, VOTEG, QUITS, LISTP, CUSRN,CPING,
//Server Responses
MSGRS, SEROR;
MSGRS, SEROR, SPING;
}
private static HashMap<String, NTtBCommands> initializeMapping(){

View File

@ -1,5 +1,6 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.server;
import ch.unibas.dmi.dbis.cs108.multiplayer.protocol.NTtBFormatMsg;
import java.io.*;
import java.net.Socket;
import java.util.HashSet;
@ -12,7 +13,7 @@ public class ClientHandler implements Runnable {
private Socket socket;
Scanner sc;
public static HashSet<ClientHandler> connectedClients = new HashSet<>();
public static HashSet<ClientHandler> inGameClients = new HashSet<>();
public static HashSet<ClientHandler> lobby = new HashSet<>();
public static HashSet<ClientHandler> ghostClients = new HashSet<>();
private ClientMsgDecoder clientMsgDecoder = new ClientMsgDecoder();
@ -35,19 +36,47 @@ public class ClientHandler implements Runnable {
}
}
//Getters:
public BufferedWriter getOut() {
return out;
}
public BufferedReader getIn() {
return in;
}
public static HashSet<ClientHandler> getConnectedClients() {
return connectedClients;
}
public static HashSet<ClientHandler> getLobby() {
return lobby;
}
public static HashSet<ClientHandler> getGhostClients() {
return ghostClients;
}
public ClientMsgDecoder getClientMsgDecoder() {
return clientMsgDecoder;
}
//Setters
@Override
/**
* point of contact for client and server.
*/
public void run() {
String msg;
String response;
NTtBFormatMsg response;
while(socket.isConnected()) {
try {
msg = in.readLine();
response = clientMsgDecoder.decodeMsg(msg).getMessage(); //The response of the server to the clients message
out.write(response);
response = clientMsgDecoder.decodeMsg(msg); //The response of the server to the clients message
out.write(response.getMessage());
out.newLine();
out.flush();
//TODO if merely an acknowledgement is sent back to the client, how does the client recieve game updates?

View File

@ -6,43 +6,36 @@ import ch.unibas.dmi.dbis.cs108.multiplayer.protocol.NoLegalProtocolCommandStrin
import ch.unibas.dmi.dbis.cs108.multiplayer.protocol.ProtocolDecoder;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class ClientMsgDecoder implements ProtocolDecoder {
private NightTrainProtocol protocol;
@Override
//TODO this method IS NOT FINNISHED. @return is not correct as of now!
public NTtBFormatMsg decodeMsg(String msg) {
List<String> msgTokens = tokenizeMsg(msg); //List where we'll put the string tokens seperated by $.
String cmd; //The command token
//Declare needed variables
String[] msgTokens; //List where we'll put the string tokens seperated by $.
String ackMsg; //The command token
String[] parameters;
NightTrainProtocol.NTtBCommands cmdObject;
Queue<String> parameters;
NTtBFormatMsg util = new NTtBFormatMsg();
cmd = serverResponseBuilder(msgTokens);
cmdObject = getCommandConstant(cmd);
util.setCommand(cmdObject);
try{
cmd = getCommandStringToken(msgTokens);
} catch (NoCommandTokenException e) {
//TODO: decide what to do here. How can we catch this smartly and where do we send it?
System.out.println(("ClientMsgDecoder cannot find a command token"));
e.printStackTrace(System.out);
return new NTtBFormatMsg("ERROR$NoCommandTokenException caught!", null, null);
}
return null;
//Initalize fields for return object
msgTokens = tokenizeMsg(msg);
ackMsg = serverResponseBuilder(msgTokens);
parameters = new String[msgTokens.length-1];
cmdObject = getCommandConstant(msgTokens[0]);
return new NTtBFormatMsg(ackMsg, cmdObject, parameters);
}
/*
* Builds the servers response message
* to client
*/
private String serverResponseBuilder(List<String> msgTokens){
private String serverResponseBuilder(String[] msgTokens) {
StringBuilder sb = new StringBuilder();
//assumes not empty list!
NightTrainProtocol.NTtBCommands cmd = getCommandConstant(msgTokens.get(0));
NightTrainProtocol.NTtBCommands cmd = getCommandConstant(msgTokens[0]);
sb.append("SERVER: ");
sb.append("Command *" + cmd.toString() + "* recieved!");
@ -53,13 +46,15 @@ public class ClientMsgDecoder implements ProtocolDecoder {
private boolean isLegalCmdString(String cmd) {
return protocol.isLegalCmdString(cmd);
}
private String getCommandStringToken(List<String> msgTokens) throws NoCommandTokenException {
return msgTokens.get(0);
private String getCommandStringToken(String[] msgTokens) throws NoCommandTokenException {
return msgTokens[0];
}
private NightTrainProtocol.NTtBCommands getCommandConstant(String stringToken) {
try{
try {
return protocol.getCmdEnumObject(stringToken);
}catch (NoLegalProtocolCommandStringFoundException e) {
} catch (NoLegalProtocolCommandStringFoundException e) {
e.printStackTrace();
e.getMessage();
} finally {
@ -69,8 +64,9 @@ public class ClientMsgDecoder implements ProtocolDecoder {
}
//Creates tokens from the clientMsg and puts them in a list
private List<String> tokenizeMsg(String msg) {
return null;
//TODO what side effects could be here?
private String[] tokenizeMsg(String msg) {
return msg.split("$");
}
/*

View File

@ -0,0 +1,73 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.server.cmd.methods;
import ch.unibas.dmi.dbis.cs108.multiplayer.protocol.NTtBFormatMsg;
import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler;
import java.io.IOException;
/**
* This Class implements actually acting on the clients
* messages.
*/
public class CommandExecuter {
ClientHandler caller;
public static void execute(NTtBFormatMsg msg) {
switch (msg.getCommand()) {
case CRTGM:
break;
case CHATA:
broadcastClientMsg(msg.getParameters());
break;
case CHATG:
//TODO
break;
case LEAVG:
//TODO
break;
case JOING:
//TODO
break;
case VOTEG:
//TODO
break;
case QUITS:
quitServer();
break;
case CHATW:
wisper(msg.getParameters());
break;
case LISTP:
//TODO
break;
case CUSRN:
changeNickname(msg.getParameters());
break;
case CPING:
pongS();
break;
case MSGRS:
//TODO
break;
case SEROR:
//TODO
break;
case SPING:
pongC();
break;
}
}
/**
* boradcast chat message to everyone
* @param parameters should only have one entry i.e.
* parameters.length == 1
* should be true;
*/
private static void broadcastClientMsg(String[] parameters) throws IOException {
for(ClientHandler clients: ClientHandler.connectedClients) {
clients.getOut().write(parameters[0]);
}
}
}

View File

@ -0,0 +1,8 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.server.cmd.methods;
public interface msgToMethod {
void quit();
}