chat packets sent to server and then sent back to all clients. #story[1246]

This commit is contained in:
Peter Galloway
2017-08-30 20:42:11 +12:00
parent 353dd48829
commit 4ebf7d6104
8 changed files with 68 additions and 108 deletions
+10 -16
View File
@@ -15,6 +15,7 @@ import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import seng302.gameServer.messages.BoatAction;
import seng302.gameServer.messages.BoatStatus;
import seng302.gameServer.messages.ChatterMessage;
import seng302.gameServer.messages.CustomizeRequestType;
import seng302.gameServer.messages.MarkRoundingMessage;
import seng302.gameServer.messages.MarkType;
@@ -41,7 +42,6 @@ public class GameState implements Runnable {
@FunctionalInterface
interface NewMessageListener {
void notify(Message message);
}
@@ -72,19 +72,9 @@ public class GameState implements Runnable {
private static Set<Mark> marks;
private static List<Limit> courseLimit;
private static List<NewMessageListener> markListeners;
private static List<NewMessageListener> messageListeners;
private static Map<Player, String> playerStringMap = new HashMap<>();
/*
Ideally I would like to make this class an object instantiated by the server and given to
it's created threads if necessary. Outside of that I think the dependencies on it
(atm only Yacht & GameClient) can be removed from most other classes. The observable list of
players could be pulled directly from the server by the GameClient since it instantiates it
and it is reasonable for it to pull data. The current setup of publicly available statics is
pretty meh IMO because anything can change it making it unreliable and like people did with
the old ServerParser class everything that needs shared just gets thrown in the static
collections and things become a real mess.
*/
public GameState(String hostIpAddress) {
windDirection = 180d;
@@ -100,7 +90,7 @@ public class GameState implements Runnable {
//set this when game stage changes to prerace
previousUpdateTime = System.currentTimeMillis();
markOrder = new MarkOrder(); //This could be instantiated at some point with a select map?
markListeners = new ArrayList<>();
messageListeners = new ArrayList<>();
resetStartTime();
@@ -671,8 +661,8 @@ public class GameState implements Runnable {
}
private static void notifyMessageListeners(Message message) {
for (NewMessageListener mpl : markListeners) {
mpl.notify(message);
for (NewMessageListener ml : messageListeners) {
ml.notify(message);
}
}
@@ -685,7 +675,7 @@ public class GameState implements Runnable {
public static void addMarkPassListener(NewMessageListener listener) {
markListeners.add(listener);
messageListeners.add(listener);
}
public static void setCustomizationFlag() {
@@ -699,4 +689,8 @@ public class GameState implements Runnable {
public static void resetCustomizationFlag() {
customizationFlag = false;
}
public static void broadcastChatter(ChatterMessage chatterMessage) {
notifyMessageListeners(chatterMessage);
}
}
@@ -2,6 +2,7 @@ package seng302.gameServer;
import java.util.Arrays;
import seng302.gameServer.messages.BoatAction;
import seng302.gameServer.messages.ChatterMessage;
import seng302.gameServer.messages.ClientType;
import seng302.gameServer.messages.CustomizeRequestType;
import seng302.gameServer.messages.Message;
@@ -28,5 +29,11 @@ public class ServerPacketParser {
long type = Message.bytesToLong(Arrays.copyOfRange(payload, 4, 5));
return CustomizeRequestType.getRequestType((int) type);
}
public static ChatterMessage extractChatterText(byte[] payload) {
return new ChatterMessage(
payload[1], new String(Arrays.copyOfRange(payload, 3, payload.length))
);
}
}
@@ -22,6 +22,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import seng302.gameServer.messages.BoatAction;
import seng302.gameServer.messages.BoatLocationMessage;
import seng302.gameServer.messages.ChatterMessage;
import seng302.gameServer.messages.ClientType;
import seng302.gameServer.messages.CustomizeRequestType;
import seng302.gameServer.messages.Message;
@@ -225,7 +226,11 @@ public class ServerToClientThread implements Runnable, Observer {
completeRegistration(requestedType);
break;
case CHATTER_TEXT:
GameState.broadcastChatter(
ServerPacketParser.extractChatterText(payload)
);
break;
case RACE_CUSTOMIZATION_REQUEST:
Long sourceID = Message
.bytesToLong(Arrays.copyOfRange(payload, 0, 3));
@@ -2,9 +2,11 @@ package seng302.utilities;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.util.Pair;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -62,31 +64,10 @@ public class StreamParser {
long windDir = bytesToLong(Arrays.copyOfRange(payload, 18, 20));
long rawWindSpeed = bytesToLong(Arrays.copyOfRange(payload, 20, 22));
// DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
// currentTime = format.format((new Date(currentTime)))
RaceStatusData data = new RaceStatusData(
windDir, rawWindSpeed, raceStatus, currentTime, expectedStartTime
);
// long timeTillStart =
// ((new Date(expectedStartTime)).getTime() - (new Date(currentTime)).getTime()) / 1000;
//
// if (timeTillStart > 0) {
// timeSinceStart = timeTillStart;
// } else {
// if (raceStatus == 4 || raceStatus == 8) {
// raceFinished = true;
// raceStarted = false;
// } else if (!raceStarted) {
// raceStarted = true;
// raceFinished = false;
// }
// timeSinceStart = timeTillStart;
// }
//
//
int noBoats = payload[22];
int raceType = payload[23];
long boatID, estTimeAtNextMark, estTimeAtFinish;
@@ -106,24 +87,6 @@ public class StreamParser {
return data;
}
// private static void setBoatLegPosition(Yacht updatingBoat, Integer leg){
// Integer placing = 1;
// if (leg != updatingBoat.getLegNumber() && (raceStarted || raceFinished)) {
// for (Yacht boat : boats.values()) {
// if (boat.getLegNumber() != null && leg <= boat.getLegNumber()){
// placing += 1;
// }
// }
// updatingBoat.setPlacing(placing.toString());
// updatingBoat.setLegNumber(leg);
// boatsPos.putIfAbsent(placing, updatingBoat);
// boatsPos.replace(placing, updatingBoat);
// } else if(updatingBoat.getLegNumber() == null){
// updatingBoat.setPlacing("1");
// updatingBoat.setLegNumber(leg);
// }
// }
/**
* Parses and returns the text from a StreamPacket containing text data for display.
*
@@ -255,15 +218,15 @@ public class StreamParser {
* @return Chatter text message as a string. Returns null if the packet is not of type
* CHATTER_TEXT.
*/
public static String extractChatterText(StreamPacket packet) {
public static Pair<Integer, String> extractChatterText(StreamPacket packet) {
if (packet.getType() != PacketType.CHATTER_TEXT) {
return null;
}
byte[] payload = packet.getPayload();
int messageVersionNo = payload[0];
int messageType = payload[1];
int length = payload[2];
return new String(Arrays.copyOfRange(payload, 3, 3 + length));
int length = (int) bytesToLong(new byte[]{payload[2]});
return new Pair<>(messageType, new String(Arrays.copyOfRange(payload, 3, 3 + length)));
}
/**
@@ -392,26 +355,6 @@ public class StreamParser {
};
}
public static void extractBoatAction(StreamPacket packet) {
byte[] payload = packet.getPayload();
int messageVersionNo = payload[0];
long actionType = bytesToLong(Arrays.copyOfRange(payload, 0, 1));
if (actionType == 1) {
System.out.println("VMG");
} else if (actionType == 2) {
System.out.println("SAILS IN");
} else if (actionType == 3) {
System.out.println("SAILS OUT");
} else if (actionType == 4) {
System.out.println("TACK/GYBE");
} else if (actionType == 5) {
System.out.println("UPWIND");
} else if (actionType == 6) {
System.out.println("DOWNWIND");
}
}
/**
* takes an array of up to 7 bytes and returns a positive long constructed from the input bytes
*
@@ -288,7 +288,7 @@ public class ClientToServerThread implements Runnable {
}
public void sendChatterMessage(String message) {
sendByteBuffer(new ChatterMessage(5, message).getBuffer());
sendByteBuffer(new ChatterMessage(clientId, message).getBuffer());
}
private void sendByteBuffer(byte[] bytes) {
@@ -1,8 +1,12 @@
package seng302.visualiser;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
import javafx.application.Platform;
@@ -15,6 +19,7 @@ import javafx.scene.control.Alert.AlertType;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.util.Pair;
import seng302.gameServer.GameState;
import seng302.gameServer.MainServerThread;
import seng302.gameServer.messages.BoatAction;
@@ -198,12 +203,13 @@ public class GameClient {
raceView.loadRace(allBoatsMap, courseData, raceState, player);
raceView.getSendPressedProperty().addListener((obs, old, isPressed) -> {
if (isPressed) {
socketThread.sendChatterMessage(raceView.readChatInput());
formatAndSendChatMessage(raceView.readChatInput());
}
});
}
private void loadFinishScreenView() {
FXMLLoader fxmlLoader = loadFXMLToHolder("/views/FinishScreenView.fxml");
FinishScreenViewController controller = fxmlLoader.getController();
@@ -287,6 +293,14 @@ public class GameClient {
case YACHT_EVENT_CODE:
showCollisionAlert(StreamParser.extractYachtEventCode(packet));
break;
case CHATTER_TEXT:
Pair<Integer, String> playerIdMessagePair = StreamParser
.extractChatterText(packet);
raceView.updateChatHistory(
allBoatsMap.get(playerIdMessagePair.getKey()).getColour(),
playerIdMessagePair.getValue()
);
}
}
}
@@ -382,7 +396,7 @@ public class GameClient {
private void keyPressed(KeyEvent e) {
if (raceView.isChatInputFocused()) {
if (e.getCode() == KeyCode.ENTER) {
socketThread.sendChatterMessage(raceView.readChatInput());
formatAndSendChatMessage(raceView.readChatInput());
}
return;
}
@@ -433,4 +447,14 @@ public class GameClient {
);
}
}
private void formatAndSendChatMessage(String rawChat) {
if (rawChat.length() > 0) {
socketThread.sendChatterMessage(
new SimpleDateFormat("[HH:mm:ss] ").format(new Date()) +
allBoatsMap.get(socketThread.getClientId()).getShortName() + ": " + rawChat
);
}
}
}
@@ -57,6 +57,8 @@ import seng302.visualiser.fxObjects.BoatObject;
*/
public class RaceViewController extends Thread implements ImportantAnnotationDelegate {
private final int CHAT_LIMIT = 128;
@FXML
private Pane basePane;
@FXML
@@ -113,10 +115,14 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
raceSparkLine.visibleProperty().setValue(false);
raceSparkLine.getYAxis().setAutoRanging(false);
sparklineYAxis.setTickMarkVisible(false);
positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
selectAnnotationBtn.setOnAction(event -> loadSelectAnnotationView());
chatInput.lengthProperty().addListener((obs, oldLen, newLen) -> {
if (newLen.intValue() > CHAT_LIMIT) {
chatInput.setText(chatInput.getText().substring(0, CHAT_LIMIT));
}
});
}
public void loadRace (
@@ -650,9 +656,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
return chat;
}
// @FXML
// public void onSendAction() {
//
// chatHistory.setText(chatHistory.getText() + chatInput.getText() + '\n');
// }
public void updateChatHistory(Paint playerColour, String newMessage) {
chatHistory.setText(chatHistory.getText() + newMessage + '\n');
}
}
+2 -20
View File
@@ -6,23 +6,6 @@
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="998.0" prefWidth="1530.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.RaceViewController">
<children>
@@ -57,7 +40,8 @@
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<TextArea fx:id="chatHistory" editable="false"
focusTraversable="false" VBox.vgrow="ALWAYS"/>
focusTraversable="false" wrapText="true"
VBox.vgrow="ALWAYS"/>
<HBox VBox.vgrow="NEVER">
<children>
<TextField fx:id="chatInput"
@@ -74,8 +58,6 @@
</AnchorPane>
</children>
</AnchorPane>
<Text fx:id="fpsDisplay" strokeType="OUTSIDE" strokeWidth="0.0" text="60 FPS"
GridPane.halignment="CENTER" GridPane.valignment="CENTER"/>
</children>
</GridPane>
</children>