me when i forget to commit my stuff.
This commit is contained in:
parent
f02aaa461a
commit
9a1e6e925a
6
.gitignore
vendored
6
.gitignore
vendored
@ -40,4 +40,8 @@ bin/
|
|||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
## Logs ##
|
||||||
|
/server/logs/
|
||||||
|
/client/logs/
|
||||||
|
|||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@ -1,18 +1,32 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "net.xircon"
|
group = "net.xircon"
|
||||||
version = "1.0-SNAPSHOT"
|
version = "1.0-SNAPSHOT"
|
||||||
|
|
||||||
|
val log4jVersion = "2.25.1"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation(platform("org.junit:junit-bom:5.10.0"))
|
implementation (platform("org.apache.logging.log4j:log4j-bom:$log4jVersion"))
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
implementation("org.apache.logging.log4j:log4j-core:$log4jVersion")
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
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 {
|
tasks.test {
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
package net.xircon;
|
|
||||||
|
|
||||||
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
|
|
||||||
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
//TIP Press <shortcut actionId="ShowIntentionActions"/> 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 <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
|
|
||||||
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.
|
|
||||||
System.out.println("i = " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
143
client/src/main/java/net/xircon/xenon/client/Xenon.java
Normal file
143
client/src/main/java/net/xircon/xenon/client/Xenon.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
client/src/main/java/net/xircon/xenon/client/io/Log.java
Normal file
25
client/src/main/java/net/xircon/xenon/client/io/Log.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
58
client/src/main/java/net/xircon/xenon/client/io/Util.java
Normal file
58
client/src/main/java/net/xircon/xenon/client/io/Util.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
5
client/src/main/resources/client.properties
Normal file
5
client/src/main/resources/client.properties
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Client Properties
|
||||||
|
PortText=49180
|
||||||
|
PortVoIP=49190
|
||||||
|
Width=960
|
||||||
|
Height=600
|
||||||
12
client/src/main/resources/log4j2.properties
Normal file
12
client/src/main/resources/log4j2.properties
Normal file
@ -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
|
||||||
@ -1,18 +1,31 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "net.xircon"
|
group = "net.xircon"
|
||||||
version = "1.0-SNAPSHOT"
|
version = "1.0-SNAPSHOT"
|
||||||
|
|
||||||
|
val log4jVersion = "2.25.1"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation(platform("org.junit:junit-bom:5.10.0"))
|
implementation (platform("org.apache.logging.log4j:log4j-bom:$log4jVersion"))
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
implementation("org.apache.logging.log4j:log4j-core:$log4jVersion")
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
implementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass = "net.xircon.xenon.server.Xenon"
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.test {
|
tasks.test {
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
56
server/src/main/java/net/xircon/xenon/server/Xenon.java
Normal file
56
server/src/main/java/net/xircon/xenon/server/Xenon.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
25
server/src/main/java/net/xircon/xenon/server/io/Log.java
Normal file
25
server/src/main/java/net/xircon/xenon/server/io/Log.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
57
server/src/main/java/net/xircon/xenon/server/io/Util.java
Normal file
57
server/src/main/java/net/xircon/xenon/server/io/Util.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
# Server.properties
|
||||||
|
PortText=49180
|
||||||
|
PortVoIP=49190
|
||||||
|
ServerName=Xircon's Test Server
|
||||||
Loading…
x
Reference in New Issue
Block a user