diff --git a/.gitignore b/.gitignore
index 1fac4d5..0890712 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,4 +40,8 @@ bin/
.vscode/
### Mac OS ###
-.DS_Store
\ No newline at end of file
+.DS_Store
+
+## Logs ##
+/server/logs/
+/client/logs/
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 5cd9a10..5b99cf8 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,7 @@
-
+
\ No newline at end of file
diff --git a/client/build.gradle.kts b/client/build.gradle.kts
index de765f9..0b45225 100644
--- a/client/build.gradle.kts
+++ b/client/build.gradle.kts
@@ -1,18 +1,32 @@
plugins {
id("java")
+ application
}
group = "net.xircon"
version = "1.0-SNAPSHOT"
+val log4jVersion = "2.25.1"
+
repositories {
mavenCentral()
}
dependencies {
- testImplementation(platform("org.junit:junit-bom:5.10.0"))
- testImplementation("org.junit.jupiter:junit-jupiter")
- testRuntimeOnly("org.junit.platform:junit-platform-launcher")
+ implementation (platform("org.apache.logging.log4j:log4j-bom:$log4jVersion"))
+ implementation("org.apache.logging.log4j:log4j-core:$log4jVersion")
+ implementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
+ implementation("com.formdev:flatlaf:3.7")
+}
+
+java {
+ toolchain {
+ languageVersion = JavaLanguageVersion.of(17)
+ }
+}
+
+application {
+ mainClass = "net.xircon.xenon.client.Xenon"
}
tasks.test {
diff --git a/client/src/main/java/net/xircon/Main.java b/client/src/main/java/net/xircon/Main.java
deleted file mode 100644
index aeaa351..0000000
--- a/client/src/main/java/net/xircon/Main.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package net.xircon;
-
-//TIP To Run code, press or
-// click the icon in the gutter.
-public class Main {
- public static void main(String[] args) {
- //TIP Press with your caret at the highlighted text
- // to see how IntelliJ IDEA suggests fixing it.
- System.out.printf("Hello and welcome!");
-
- for (int i = 1; i <= 5; i++) {
- //TIP Press to start debugging your code. We have set one breakpoint
- // for you, but you can always add more by pressing .
- System.out.println("i = " + i);
- }
- }
-}
\ No newline at end of file
diff --git a/client/src/main/java/net/xircon/xenon/client/Xenon.java b/client/src/main/java/net/xircon/xenon/client/Xenon.java
new file mode 100644
index 0000000..cefe0cd
--- /dev/null
+++ b/client/src/main/java/net/xircon/xenon/client/Xenon.java
@@ -0,0 +1,143 @@
+package net.xircon.xenon.client;
+
+
+import com.formdev.flatlaf.FlatDarkLaf;
+import net.xircon.xenon.client.io.Log;
+import net.xircon.xenon.client.io.Util;
+import net.xircon.xenon.client.networking.Networking;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.net.Socket;
+import java.util.Objects;
+
+public class Xenon implements Runnable {
+ private Thread mainThread;
+ public static void main(String[] args) {new Xenon().start();}
+ private static Socket mainSocket;
+
+ static final String propertiesFile = "client.properties";
+ // Properties
+ public static int PortVoIP = 49190;
+ public static int PortText = 49180;
+ public static int Width = 800;
+ public static int Height = 600;
+
+ private static String nickname = "Test User";
+
+ public void start() {
+ mainThread = new Thread(this, "mainThread");
+ mainThread.start();
+ }
+
+ @Override
+ public void run() {
+ Log.info("Starting Xenon Client!");
+ // Get Property Values
+ PortVoIP = Objects.requireNonNull(Util.GetProperties(propertiesFile, "PortVoIP", Util.PROPERTY_TYPE_INT)).intValue;
+ PortText = Objects.requireNonNull(Util.GetProperties(propertiesFile, "PortText", Util.PROPERTY_TYPE_INT)).intValue;
+ Width = Objects.requireNonNull(Util.GetProperties(propertiesFile, "Width", Util.PROPERTY_TYPE_INT)).intValue;
+ Height = Objects.requireNonNull(Util.GetProperties(propertiesFile, "Height", Util.PROPERTY_TYPE_INT)).intValue;
+
+ // Start Java Swing GUI
+ JFrame mainFrame = new JFrame("Xenon Client");
+ mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ mainFrame.setSize(Width, Height);
+ try {
+ UIManager.setLookAndFeel( new FlatDarkLaf());
+ } catch (UnsupportedLookAndFeelException e) {
+ Log.err("Java Swing GUI Look and Feel Did Not Correctly Apply! Falling Back to Default!");
+ }
+
+ // Creating the MenuBar and adding components
+ JMenuBar mb = new JMenuBar();
+ // Menu 1
+ JMenu m1 = new JMenu("File");
+ JMenuItem m11 = new JMenuItem("Open");
+ JMenuItem m12 = new JMenuItem("Save as");
+ mb.add(m1);
+ m1.add(m11);
+ m1.add(m12);
+ // Menu 2
+ JMenu m2 = new JMenu("Connections");
+ JMenuItem m21 = new JMenuItem(new AbstractAction("Connect To Server") {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String IPAddress = JOptionPane.showInputDialog(null, "IP Address Of Server", "127.0.0.1");
+ if (IPAddress == null) {return;}
+ else {
+ mainSocket = Networking.connectToServer(IPAddress, PortText);
+ }
+ }
+ });
+ JMenuItem m22 = new JMenuItem(new AbstractAction("Disconnect From Server") {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Networking.disconnectFromServer(mainSocket);
+ }
+ });
+ JMenuItem m23 = new JMenuItem(new AbstractAction("Change Nickname") {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String Nick = JOptionPane.showInputDialog(null, "New Nickname", nickname);
+ if (Nick == null) {return;}
+ else {
+ nickname = Nick;
+ }
+ }
+ });
+ mb.add(m2);
+ m2.add(m21);
+ m2.add(m22);
+ m2.add(m23);
+ // Menu 3
+ JMenu m3 = new JMenu("Help");
+ JMenuItem m31 = new JMenuItem(new AbstractAction("About") {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent) {
+ JOptionPane.showMessageDialog(null, "Xenon Created By Xircon\nLicenced under the GNU GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.en.html)",
+ "About Xenon", JOptionPane.INFORMATION_MESSAGE);
+ }
+ });
+ mb.add(m3);
+ m3.add(m31);
+
+
+ // Creating the panel at bottom and adding components
+ JPanel panel = new JPanel(); // the panel is not visible in output
+ panel.setLayout(new BorderLayout());
+ JTextField sendField = new JTextField(); // accepts up to 255 characters
+ sendField.setToolTipText("Enter Message");
+ sendField.setPreferredSize(new Dimension(200 ,20 ));
+ JButton send = new JButton("Send");
+ JButton upload = new JButton("Upload");
+ panel.add(sendField, BorderLayout.CENTER);
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new BorderLayout());
+ buttonPanel.add(send, BorderLayout.WEST);
+ buttonPanel.add(upload, BorderLayout.EAST);
+ panel.add(buttonPanel, BorderLayout.EAST);
+
+ // Text Sending Handler
+ send.addActionListener(e -> {
+ if (mainSocket == null) {JOptionPane.showMessageDialog(null, "Ensure you are Connected to a Server!", "Error", JOptionPane.ERROR_MESSAGE);}
+ else {
+ Log.info("Sending " + sendField.getText());
+ Networking.sendMessage(sendField.getText(), nickname, mainSocket);
+ SwingUtilities.invokeLater(() -> sendField.setText(""));
+ }
+ });
+
+ // Text Area at the Center
+ JTextArea ta = new JTextArea();
+
+ //Adding Components to the Frame.
+ mainFrame.getContentPane().add(BorderLayout.SOUTH, panel);
+ mainFrame.getContentPane().add(BorderLayout.NORTH, mb);
+ mainFrame.getContentPane().add(BorderLayout.CENTER, ta);
+ // Set GUI To Visible
+ mainFrame.setVisible(true);
+ }
+}
\ No newline at end of file
diff --git a/client/src/main/java/net/xircon/xenon/client/io/Log.java b/client/src/main/java/net/xircon/xenon/client/io/Log.java
new file mode 100644
index 0000000..d64d4e7
--- /dev/null
+++ b/client/src/main/java/net/xircon/xenon/client/io/Log.java
@@ -0,0 +1,25 @@
+package net.xircon.xenon.client.io;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.swing.*;
+
+public class Log {
+ public static final Logger logger = LogManager.getLogger();
+
+ public static void fatal(String message) {
+ logger.fatal(message);
+ JOptionPane.showMessageDialog(null, message, "Fatal Error", JOptionPane.ERROR_MESSAGE);
+ throw new RuntimeException(message);
+ }
+ public static void err(String message) {
+ logger.error(message);
+ }
+ public static void warn(String message) {
+ logger.warn(message);
+ }
+ public static void info(String message) {
+ logger.info(message);
+ }
+}
diff --git a/client/src/main/java/net/xircon/xenon/client/io/Util.java b/client/src/main/java/net/xircon/xenon/client/io/Util.java
new file mode 100644
index 0000000..61603a5
--- /dev/null
+++ b/client/src/main/java/net/xircon/xenon/client/io/Util.java
@@ -0,0 +1,58 @@
+package net.xircon.xenon.client.io;
+
+import javax.annotation.Nullable;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Properties;
+
+public class Util {
+ public static class Property {
+ public boolean boolValue = false;
+ public int intValue = 0;
+ public String stringValue = "";
+ }
+
+ public static final int PROPERTY_TYPE_BOOLEAN = 1;
+ public static final int PROPERTY_TYPE_INT = 2;
+ public static final int PROPERTY_TYPE_STRING = 3;
+
+ @Nullable
+ public static Property GetProperties(String propertiesFile, String propertyName, int propertyType) {
+ Properties properties = new Properties();
+ Property property = new Property();
+ if (false); // TODO: Add Checker for file later, and make fallback to resources folder
+ else try (InputStream propertiesinput = Util.class.getClassLoader().getResourceAsStream(propertiesFile)) {
+ properties.load(propertiesinput);
+ if (properties.containsKey(propertyName) && propertyType == PROPERTY_TYPE_BOOLEAN) { // Booleans
+ String prop = properties.getProperty(propertyName);
+ property.boolValue = prop.equals("true");
+ return property;
+ }
+ if (properties.containsKey(propertyName) && propertyType == PROPERTY_TYPE_INT) { // Ints
+ int prop = Integer.parseInt(properties.getProperty(propertyName));
+ if (prop >=0 ) property.intValue=prop;
+ return property;
+ }
+ if (properties.containsKey(propertyName) && propertyType == PROPERTY_TYPE_STRING) { // Strings
+ String prop = properties.getProperty(propertyName);
+ if (prop != null ) property.stringValue=prop;
+ return property;
+ }
+ } catch (IOException e) {
+ Log.warn("[Property Loader] Failed to Read server.properties! Falling Back to Defaults! {" + e.getMessage() + "}");
+ }
+ Log.warn("[Property Loader] Unable to Find Property/Invalid Type!");
+ return null;
+ }
+ public static String GetExternalIP() throws IOException {
+ URL whatismyip = new URL("http://checkip.amazonaws.com");
+ BufferedReader in = new BufferedReader(new InputStreamReader(
+ whatismyip.openStream()));
+
+ // Return IP As String
+ return in.readLine();
+ }
+}
diff --git a/client/src/main/java/net/xircon/xenon/client/networking/Networking.java b/client/src/main/java/net/xircon/xenon/client/networking/Networking.java
new file mode 100644
index 0000000..324448b
--- /dev/null
+++ b/client/src/main/java/net/xircon/xenon/client/networking/Networking.java
@@ -0,0 +1,61 @@
+package net.xircon.xenon.client.networking;
+
+import net.xircon.xenon.client.io.Log;
+
+import javax.annotation.Nullable;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketTimeoutException;
+
+public class Networking {
+ private static final String nameTerminator = "\uffff";
+
+ @Nullable
+ public static Socket connectToServer(String Address, int Port) {
+ try {
+ Log.info("Connecting To Server " + Address + ":" + Port);
+ Socket socket = new Socket();
+ SocketAddress address = new InetSocketAddress(Address, Port);
+ socket.connect(address, 5000);
+ Log.info("Connected to Server!");
+ socket.setKeepAlive(true);
+ return socket;
+ } catch (SocketTimeoutException e) {
+ Log.warn("Connection timed out!");
+ return null;
+ } catch (Exception e) {
+ Log.err("Failed to Connect to Server!");
+ return null;
+ }
+ }
+
+ public static void disconnectFromServer(Socket socket) {
+ try {
+ Log.info("Disconnecting from Server");
+ socket.close();
+ } catch (IOException e) {
+ Log.err("Failed to Close Socket!");
+ } catch (NullPointerException e) {
+ Log.warn("Ignoring Disconnect Request, Null Socket!");
+ }
+ }
+
+ public static String sendMessage(String message, String nickname, Socket socket) {
+ try {
+ BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
+ output.println(nickname + nameTerminator + message);
+ String messageFromServer = input.readLine();
+ Log.info("Server Message: " + messageFromServer);
+ return messageFromServer;
+ } catch (IOException e) {
+ Log.warn("Could not Read/Send Message!");
+ return null;
+ }
+ }
+}
diff --git a/client/src/main/java/net/xircon/xenon/client/networking/textclient/TextClient.java b/client/src/main/java/net/xircon/xenon/client/networking/textclient/TextClient.java
new file mode 100644
index 0000000..37de8c0
--- /dev/null
+++ b/client/src/main/java/net/xircon/xenon/client/networking/textclient/TextClient.java
@@ -0,0 +1,15 @@
+package net.xircon.xenon.client.networking.textclient;
+
+import java.net.Socket;
+
+public class TextClient implements Runnable {
+
+ public TextClient(Socket serverSocket) {
+
+ }
+
+ @Override
+ public void run() {
+
+ }
+}
diff --git a/client/src/main/resources/client.properties b/client/src/main/resources/client.properties
new file mode 100644
index 0000000..4068efe
--- /dev/null
+++ b/client/src/main/resources/client.properties
@@ -0,0 +1,5 @@
+# Client Properties
+PortText=49180
+PortVoIP=49190
+Width=960
+Height=600
\ No newline at end of file
diff --git a/client/src/main/resources/log4j2.properties b/client/src/main/resources/log4j2.properties
new file mode 100644
index 0000000..485380b
--- /dev/null
+++ b/client/src/main/resources/log4j2.properties
@@ -0,0 +1,12 @@
+appender.console.type=Console
+appender.console.name=STDOUT
+appender.console.layout.type=PatternLayout
+appender.console.layout.pattern=[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%t] %msg%n
+appender.file.type=File
+appender.file.name=LOGFILE
+appender.file.fileName=logs/technitium.log
+appender.file.layout.type=PatternLayout
+appender.file.layout.pattern=[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%t] %msg%n
+appender.file.filter.threshold.type = ThresholdFilter
+appender.file.filter.threshold.level = info
+rootLogger=debug, STDOUT, LOGFILE
\ No newline at end of file
diff --git a/server/build.gradle.kts b/server/build.gradle.kts
index de765f9..53cfc8f 100644
--- a/server/build.gradle.kts
+++ b/server/build.gradle.kts
@@ -1,18 +1,31 @@
plugins {
id("java")
+ application
}
group = "net.xircon"
version = "1.0-SNAPSHOT"
+val log4jVersion = "2.25.1"
+
repositories {
mavenCentral()
}
dependencies {
- testImplementation(platform("org.junit:junit-bom:5.10.0"))
- testImplementation("org.junit.jupiter:junit-jupiter")
- testRuntimeOnly("org.junit.platform:junit-platform-launcher")
+ implementation (platform("org.apache.logging.log4j:log4j-bom:$log4jVersion"))
+ implementation("org.apache.logging.log4j:log4j-core:$log4jVersion")
+ implementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
+}
+
+java {
+ toolchain {
+ languageVersion = JavaLanguageVersion.of(17)
+ }
+}
+
+application {
+ mainClass = "net.xircon.xenon.server.Xenon"
}
tasks.test {
diff --git a/server/src/main/java/net/xircon/Main.java b/server/src/main/java/net/xircon/Main.java
deleted file mode 100644
index 80eff76..0000000
--- a/server/src/main/java/net/xircon/Main.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package net.xircon;
-
-public class Main {
- public static void main(String[] args) {
- System.out.println()
-
- for (int i = 1; i <= 5; i++) {
- System.out.println("i = " + i);
- }
- }
-}
diff --git a/server/src/main/java/net/xircon/xenon/server/Xenon.java b/server/src/main/java/net/xircon/xenon/server/Xenon.java
new file mode 100644
index 0000000..09a1189
--- /dev/null
+++ b/server/src/main/java/net/xircon/xenon/server/Xenon.java
@@ -0,0 +1,56 @@
+package net.xircon.xenon.server;
+
+import net.xircon.xenon.server.io.*;
+import net.xircon.xenon.server.networking.Networking;
+import net.xircon.xenon.server.networking.textserver.TextServer;
+
+import java.io.IOException;
+import java.net.*;
+import java.util.Objects;
+
+//import java.net.
+
+public class Xenon implements Runnable {
+ private Thread serverThread;
+ public static void main(String[] args) {new Xenon().start();}
+
+ private ServerSocket textServerSocket;
+
+ private static final String propertiesFile = "server.properties";
+ // Sever Properties
+ public static String ServerName = "Xenon Test Server";
+ public static int PortVoIP = 49190;
+ public static int PortText = 49180;
+
+ public void start() {
+ serverThread = new Thread(this, "serverThread");
+ serverThread.start();
+ }
+
+ @Override
+ public void run() {
+ Log.info("Starting Xenon Server!");
+
+ // Get Property Values
+ PortVoIP = Objects.requireNonNull(Util.GetProperties(propertiesFile, "PortVoIP", Util.PROPERTY_TYPE_INT)).intValue;
+ PortText = Objects.requireNonNull(Util.GetProperties(propertiesFile, "PortText", Util.PROPERTY_TYPE_INT)).intValue;
+ ServerName = Objects.requireNonNull(Util.GetProperties(propertiesFile, "ServerName", Util.PROPERTY_TYPE_STRING)).stringValue;
+
+ Log.info("Server is on Port " + PortVoIP + " For VoIP and Port " + PortText + " For Text.");
+ // Print External IP and Handle IOException
+ try {
+ Log.info("Server's External IP is " + Util.GetExternalIP());
+ } catch (IOException e) {
+ Log.err("IOException Whilst Fetching External IP! {" + e + "}");
+ }
+ Log.info("Server Name is " + '"' + ServerName + '"');
+ textServerSocket = Networking.createTextServer(PortText);
+ TextServer textServer = new TextServer(textServerSocket);
+ Thread textServerThread = new Thread(textServer);
+ textServerThread.start();
+ }
+
+
+
+
+}
diff --git a/server/src/main/java/net/xircon/xenon/server/io/Log.java b/server/src/main/java/net/xircon/xenon/server/io/Log.java
new file mode 100644
index 0000000..98d5b7e
--- /dev/null
+++ b/server/src/main/java/net/xircon/xenon/server/io/Log.java
@@ -0,0 +1,25 @@
+package net.xircon.xenon.server.io;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.swing.*;
+
+public class Log {
+ public static final Logger logger = LogManager.getLogger();
+
+ public static void fatal(String message) {
+ logger.fatal(message);
+ JOptionPane.showMessageDialog(null, message, "Fatal Error", JOptionPane.ERROR_MESSAGE);
+ throw new RuntimeException(message);
+ }
+ public static void err(String message) {
+ logger.error(message);
+ }
+ public static void warn(String message) {
+ logger.warn(message);
+ }
+ public static void info(String message) {
+ logger.info(message);
+ }
+}
diff --git a/server/src/main/java/net/xircon/xenon/server/io/Util.java b/server/src/main/java/net/xircon/xenon/server/io/Util.java
new file mode 100644
index 0000000..d74a249
--- /dev/null
+++ b/server/src/main/java/net/xircon/xenon/server/io/Util.java
@@ -0,0 +1,57 @@
+package net.xircon.xenon.server.io;
+
+import javax.annotation.Nullable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.net.*;
+import java.io.*;
+
+public class Util {
+ public static class Property {
+ public boolean boolValue = false;
+ public int intValue = 0;
+ public String stringValue = "";
+ }
+
+ public static final int PROPERTY_TYPE_BOOLEAN = 1;
+ public static final int PROPERTY_TYPE_INT = 2;
+ public static final int PROPERTY_TYPE_STRING = 3;
+
+ @Nullable
+ public static Property GetProperties(String propertiesFile, String propertyName, int propertyType) {
+ Properties properties = new Properties();
+ Property property = new Property();
+ if (false); // TODO: Add Checker for file later, and make fallback to resources folder
+ else try (InputStream propertiesinput = Util.class.getClassLoader().getResourceAsStream(propertiesFile)) {
+ properties.load(propertiesinput);
+ if (properties.containsKey(propertyName) && propertyType == PROPERTY_TYPE_BOOLEAN) { // Booleans
+ String prop = properties.getProperty(propertyName);
+ property.boolValue = prop.equals("true");
+ return property;
+ }
+ if (properties.containsKey(propertyName) && propertyType == PROPERTY_TYPE_INT) { // Ints
+ int prop = Integer.parseInt(properties.getProperty(propertyName));
+ if (prop >=0 ) property.intValue=prop;
+ return property;
+ }
+ if (properties.containsKey(propertyName) && propertyType == PROPERTY_TYPE_STRING) { // Strings
+ String prop = properties.getProperty(propertyName);
+ if (prop != null ) property.stringValue=prop;
+ return property;
+ }
+ } catch (IOException e) {
+ Log.warn("[Property Loader] Failed to Read server.properties! Falling Back to Defaults! {" + e.getMessage() + "}");
+ }
+ Log.warn("[Property Loader] Unable to Find Property/Invalid Type!");
+ return null;
+ }
+ public static String GetExternalIP() throws IOException {
+ URL whatismyip = new URL("http://checkip.amazonaws.com");
+ BufferedReader in = new BufferedReader(new InputStreamReader(
+ whatismyip.openStream()));
+
+ // Return IP As String
+ return in.readLine();
+ }
+}
diff --git a/server/src/main/java/net/xircon/xenon/server/networking/Networking.java b/server/src/main/java/net/xircon/xenon/server/networking/Networking.java
new file mode 100644
index 0000000..1e50d1b
--- /dev/null
+++ b/server/src/main/java/net/xircon/xenon/server/networking/Networking.java
@@ -0,0 +1,21 @@
+package net.xircon.xenon.server.networking;
+
+import net.xircon.xenon.server.io.Log;
+
+import javax.annotation.Nullable;
+import java.io.IOException;
+import java.net.ServerSocket;
+
+public class Networking {
+ @Nullable
+ public static ServerSocket createTextServer(int Port) {
+ try {
+ ServerSocket serverSocket = new ServerSocket(Port);
+ Log.info("Text Server Waiting For Clients");
+ return serverSocket;
+ } catch (IOException e) {
+ Log.info("Failed to Create Text Server!");
+ return null;
+ }
+ }
+}
diff --git a/server/src/main/java/net/xircon/xenon/server/networking/textserver/ClientHandler.java b/server/src/main/java/net/xircon/xenon/server/networking/textserver/ClientHandler.java
new file mode 100644
index 0000000..ed69636
--- /dev/null
+++ b/server/src/main/java/net/xircon/xenon/server/networking/textserver/ClientHandler.java
@@ -0,0 +1,32 @@
+package net.xircon.xenon.server.networking.textserver;
+
+import net.xircon.xenon.server.io.Log;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.Socket;
+
+public class ClientHandler implements Runnable {
+ private Socket clientSocket;
+
+ public ClientHandler(Socket clientSocket) {
+ this.clientSocket = clientSocket;
+ }
+
+ @Override
+ public void run() {
+ try {
+ BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+ PrintWriter output = output = new PrintWriter(clientSocket.getOutputStream(), true);
+ String message = input.readLine();
+ String namedMessage[] = message.split("\uffff", -1);
+ Log.info("<" + namedMessage[0] + "> " + namedMessage[1]);
+ output.println("Server Received Message!");
+ clientSocket.setKeepAlive(true);
+ } catch (IOException e) {
+ Log.warn("Could not Read Message From Client");
+ }
+ }
+}
diff --git a/server/src/main/java/net/xircon/xenon/server/networking/textserver/TextServer.java b/server/src/main/java/net/xircon/xenon/server/networking/textserver/TextServer.java
new file mode 100644
index 0000000..326147a
--- /dev/null
+++ b/server/src/main/java/net/xircon/xenon/server/networking/textserver/TextServer.java
@@ -0,0 +1,31 @@
+package net.xircon.xenon.server.networking.textserver;
+
+import net.xircon.xenon.server.io.Log;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class TextServer implements Runnable {
+ private ServerSocket mainServerSocket;
+
+ public TextServer(ServerSocket serverSocket) {
+ this.mainServerSocket = serverSocket;
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ Socket clientSocket = mainServerSocket.accept();
+ Log.info("Client Connected: " + clientSocket);
+ ClientHandler clientHandler = new ClientHandler(clientSocket);
+ Thread thread = new Thread(clientHandler);
+ thread.start();
+ } catch (IOException e) {
+ Log.err("Text Server Did not correctly Accept a Client!");
+ }
+
+ }
+ }
+}
diff --git a/server/src/main/resources/server.properties b/server/src/main/resources/server.properties
index e69de29..b61e188 100644
--- a/server/src/main/resources/server.properties
+++ b/server/src/main/resources/server.properties
@@ -0,0 +1,4 @@
+# Server.properties
+PortText=49180
+PortVoIP=49190
+ServerName=Xircon's Test Server
\ No newline at end of file