mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
chat packets sent to server and then sent back to all clients. #story[1246]
This commit is contained in:
@@ -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');
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user