mirror of
https://github.com/ProjectSWGCore/forwarder.git
synced 2026-09-13 00:45:00 -04:00
Created an auto-login mechanism built-in to the forwarder
This commit is contained in:
@@ -8,6 +8,7 @@ import com.projectswg.ClientReceiver.ClientReceiverCallback;
|
||||
import com.projectswg.ClientReceiver.ConnectionState;
|
||||
import com.projectswg.networking.NetInterceptor;
|
||||
import com.projectswg.networking.Packet;
|
||||
import com.projectswg.networking.NetInterceptor.InterceptorProperties;
|
||||
import com.projectswg.networking.swg.HeartBeat;
|
||||
|
||||
public class ClientConnection {
|
||||
@@ -28,11 +29,20 @@ public class ClientConnection {
|
||||
receiver.setClientSender(sender);
|
||||
}
|
||||
|
||||
public InterceptorProperties getInterceptorProperties() {
|
||||
return interceptor.getProperties();
|
||||
}
|
||||
|
||||
public boolean restart() {
|
||||
stop();
|
||||
return start();
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
if (!sender.start())
|
||||
return false;
|
||||
receiver.start();
|
||||
interceptor.setPort(sender.getZonePort());
|
||||
interceptor.getProperties().setPort(sender.getZonePort());
|
||||
sender.setLoginCallback((packet) -> receiver.onPacket(false, packet));
|
||||
sender.setZoneCallback((packet) -> receiver.onPacket(true, packet));
|
||||
receiver.setReceiverCallback(new ClientReceiverCallback() {
|
||||
@@ -48,8 +58,9 @@ public class ClientConnection {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
pinger.shutdownNow();
|
||||
private void stop() {
|
||||
if (pinger != null)
|
||||
pinger.shutdownNow();
|
||||
sender.stop();
|
||||
receiver.stop();
|
||||
onDisconnected();
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
import com.projectswg.ClientConnection.ClientCallback;
|
||||
import com.projectswg.ServerConnection.ConnectionStatus;
|
||||
import com.projectswg.ServerConnection.ServerCallback;
|
||||
import com.projectswg.networking.NetInterceptor.InterceptorProperties;
|
||||
import com.projectswg.networking.swg.ErrorMessage;
|
||||
|
||||
public class Connections {
|
||||
@@ -50,7 +51,10 @@ public class Connections {
|
||||
|
||||
public void terminate() {
|
||||
server.stop();
|
||||
client.stop();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (client.restart())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCallback(ConnectionCallback callback) {
|
||||
@@ -62,7 +66,6 @@ public class Connections {
|
||||
return;
|
||||
terminate();
|
||||
server.setRemoteAddress(addr, port);
|
||||
initialize();
|
||||
}
|
||||
|
||||
public InetAddress getRemoteAddress() {
|
||||
@@ -97,6 +100,10 @@ public class Connections {
|
||||
return udpSent.get();
|
||||
}
|
||||
|
||||
public InterceptorProperties getInterceptorProperties() {
|
||||
return client.getInterceptorProperties();
|
||||
}
|
||||
|
||||
private void setCallbacks() {
|
||||
client.setCallback(new ClientCallback() {
|
||||
public void onPacket(byte[] data) { onDataSentTcp(data); }
|
||||
@@ -116,7 +123,6 @@ public class Connections {
|
||||
client.send(new ErrorMessage("Connection Update", "\n" + status.name().replace('_', ' '), false));
|
||||
try { Thread.sleep(50); } catch (InterruptedException e) { }
|
||||
terminate();
|
||||
client.start();
|
||||
}
|
||||
if (callback != null)
|
||||
callback.onServerStatusChanged(oldStatus, status);
|
||||
@@ -132,7 +138,6 @@ public class Connections {
|
||||
terminate();
|
||||
if (callback != null)
|
||||
callback.onClientDisconnected();
|
||||
client.start();
|
||||
}
|
||||
|
||||
private void onDataRecvTcp(byte [] data) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
@@ -30,6 +31,8 @@ public class Forwarder extends Application implements ConnectionCallback {
|
||||
|
||||
private final ExecutorService executor;
|
||||
private final Connections connections;
|
||||
private final TextField usernameField;
|
||||
private final TextField passwordField;
|
||||
private final TextField serverIpField;
|
||||
private final TextField serverPortField;
|
||||
private final Button serverSetButton;
|
||||
@@ -49,6 +52,8 @@ public class Forwarder extends Application implements ConnectionCallback {
|
||||
public Forwarder() {
|
||||
executor = Executors.newSingleThreadExecutor();
|
||||
connections = new Connections();
|
||||
usernameField = new TextField("");
|
||||
passwordField = new PasswordField();
|
||||
serverIpField = new TextField(connections.getRemoteAddress().getHostAddress());
|
||||
serverPortField = new TextField(Integer.toString(connections.getRemotePort()));
|
||||
serverSetButton = new Button("Set");
|
||||
@@ -71,6 +76,10 @@ public class Forwarder extends Application implements ConnectionCallback {
|
||||
updateServerButton();
|
||||
}
|
||||
};
|
||||
usernameField.promptTextProperty().setValue("Username");
|
||||
passwordField.promptTextProperty().setValue("Password");
|
||||
usernameField.textProperty().addListener((event, oldValue, newValue) -> connections.getInterceptorProperties().setUsername(newValue));
|
||||
passwordField.textProperty().addListener((event, oldValue, newValue) -> connections.getInterceptorProperties().setPassword(newValue));
|
||||
serverIpField.setOnKeyPressed(handler);
|
||||
serverPortField.setOnKeyPressed(handler);
|
||||
serverIpField.setOnKeyTyped(handler);
|
||||
@@ -162,7 +171,7 @@ public class Forwarder extends Application implements ConnectionCallback {
|
||||
clientConnectionPort.setText(Integer.toString(connections.getLoginPort()));
|
||||
GridPane root = new GridPane();
|
||||
setupGridPane(root);
|
||||
Scene scene = new Scene(root, 400, 140);
|
||||
Scene scene = new Scene(root, 400, 160);
|
||||
primaryStage.setTitle("Holocore Forwarder");
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.setMinWidth(scene.getWidth());
|
||||
@@ -190,23 +199,25 @@ public class Forwarder extends Application implements ConnectionCallback {
|
||||
addColumnConstraint(root, 100);
|
||||
addColumnConstraint(root, 75);
|
||||
addColumnConstraint(root, 175);
|
||||
root.add(serverIpField, 0, 0, 2, 1);
|
||||
root.add(serverPortField, 2, 0, 1, 1);
|
||||
root.add(serverSetButton, 3, 0, 1, 1);
|
||||
root.add(new Text("Server Connection:"), 0, 1, 2, 1);
|
||||
root.add(serverConnectionText, 2, 1, 1, 1);
|
||||
root.add(serverStatusText, 3, 1, 1, 1);
|
||||
root.add(new Text("Client Connection:"), 0, 2, 2, 1);
|
||||
root.add(clientConnectionText, 2, 2, 2, 1);
|
||||
root.add(clientConnectionPort, 3, 2, 1, 1);
|
||||
root.add(new Text("Sent"), 1, 3, 1, 1);
|
||||
root.add(new Text("Recv"), 2, 3, 1, 1);
|
||||
root.add(new Text("TCP"), 0, 4, 1, 1);
|
||||
root.add(serverTxText, 1, 4, 1, 1);
|
||||
root.add(serverRxText, 2, 4, 1, 1);
|
||||
root.add(new Text("UDP"), 0, 5, 1, 1);
|
||||
root.add(clientTxText, 1, 5, 1, 1);
|
||||
root.add(clientRxText, 2, 5, 1, 1);
|
||||
root.add(usernameField, 0, 0, 2, 1);
|
||||
root.add(passwordField, 2, 0, 2, 1);
|
||||
root.add(serverIpField, 0, 1, 2, 1);
|
||||
root.add(serverPortField, 2, 1, 1, 1);
|
||||
root.add(serverSetButton, 3, 1, 1, 1);
|
||||
root.add(new Text("Server Connection:"), 0, 2, 2, 1);
|
||||
root.add(serverConnectionText, 2, 2, 1, 1);
|
||||
root.add(serverStatusText, 3, 2, 1, 1);
|
||||
root.add(new Text("Client Connection:"), 0, 3, 2, 1);
|
||||
root.add(clientConnectionText, 2, 3, 2, 1);
|
||||
root.add(clientConnectionPort, 3, 3, 1, 1);
|
||||
root.add(new Text("Sent"), 1, 4, 1, 1);
|
||||
root.add(new Text("Recv"), 2, 4, 1, 1);
|
||||
root.add(new Text("TCP"), 0, 5, 1, 1);
|
||||
root.add(serverTxText, 1, 5, 1, 1);
|
||||
root.add(serverRxText, 2, 5, 1, 1);
|
||||
root.add(new Text("UDP"), 0, 6, 1, 1);
|
||||
root.add(clientTxText, 1, 6, 1, 1);
|
||||
root.add(clientRxText, 2, 6, 1, 1);
|
||||
}
|
||||
|
||||
private void addColumnConstraint(GridPane root, double width) {
|
||||
|
||||
@@ -4,22 +4,31 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import com.projectswg.networking.resources.Galaxy;
|
||||
import com.projectswg.networking.swg.LoginClientId;
|
||||
import com.projectswg.networking.swg.LoginClusterStatus;
|
||||
|
||||
public class NetInterceptor {
|
||||
|
||||
private int port;
|
||||
private final InterceptorProperties properties;
|
||||
|
||||
public NetInterceptor() {
|
||||
|
||||
properties = new InterceptorProperties();
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
public InterceptorProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public byte [] interceptClient(byte [] data) {
|
||||
return data;
|
||||
if (data.length < 6)
|
||||
return data;
|
||||
ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
|
||||
switch (bb.getInt(2)) {
|
||||
case 0x41131F96:
|
||||
return setAutoLogin(bb);
|
||||
default:
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public byte [] interceptServer(byte [] data) {
|
||||
@@ -34,15 +43,63 @@ public class NetInterceptor {
|
||||
}
|
||||
}
|
||||
|
||||
private byte [] setAutoLogin(ByteBuffer data) {
|
||||
LoginClientId id = new LoginClientId(data);
|
||||
if (!id.getUsername().equals(properties.getUsername()) || !id.getPassword().isEmpty()) {
|
||||
return data.array();
|
||||
}
|
||||
System.out.println("Set Password: " + properties.getPassword());
|
||||
id.setPassword(properties.getPassword());
|
||||
return id.encode().array();
|
||||
}
|
||||
|
||||
private byte [] getServerList(ByteBuffer data) {
|
||||
LoginClusterStatus cluster = new LoginClusterStatus();
|
||||
cluster.decode(data);
|
||||
for (Galaxy g : cluster.getGalaxies()) {
|
||||
g.setAddress("127.0.0.1");
|
||||
g.setZonePort((short) port);
|
||||
g.setPingPort((short) port);
|
||||
g.setZonePort((short) properties.getPort());
|
||||
g.setPingPort((short) properties.getPort());
|
||||
}
|
||||
return cluster.encode().array();
|
||||
}
|
||||
|
||||
public static class InterceptorProperties {
|
||||
|
||||
private int port;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public InterceptorProperties() {
|
||||
port = 0;
|
||||
username = "";
|
||||
password = "";
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.networking.swg;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.projectswg.networking.SWGPacket;
|
||||
|
||||
|
||||
public class LoginClientId extends SWGPacket {
|
||||
|
||||
public static final int CRC = 0x41131F96;
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
private String version;
|
||||
|
||||
public LoginClientId() {
|
||||
this("", "", "");
|
||||
}
|
||||
|
||||
public LoginClientId(ByteBuffer data) {
|
||||
decode(data);
|
||||
}
|
||||
|
||||
public LoginClientId(String username, String password, String version) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public void decode(ByteBuffer data) {
|
||||
if (!super.decode(data, CRC))
|
||||
return;
|
||||
username = getAscii(data);
|
||||
password = getAscii(data);
|
||||
version = getAscii(data);
|
||||
}
|
||||
|
||||
public ByteBuffer encode() {
|
||||
int length = 6 + 6 + username.length() + password.length() + version.length();
|
||||
ByteBuffer data = ByteBuffer.allocate(length);
|
||||
addShort(data, 4);
|
||||
addInt( data, CRC);
|
||||
addAscii(data, username);
|
||||
addAscii(data, password);
|
||||
addAscii(data, version);
|
||||
return data;
|
||||
}
|
||||
|
||||
public String getUsername() { return username; }
|
||||
public void setUsername(String str) { this.username = str; }
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String str) { this.password = str; }
|
||||
public String getVersion() { return version; }
|
||||
}
|
||||
Reference in New Issue
Block a user