Support JP and TW clients

This commit is contained in:
Melledy
2025-12-03 14:08:38 -08:00
parent 2c1e1ae2fb
commit 7ef7490c37
5 changed files with 113 additions and 39 deletions

View File

@@ -29,6 +29,14 @@ For any extra support, questions, or discussions, check out our [Discord](https:
### Not implemented ### Not implemented
- Events - Events
### Supported regions
Nebula supports the global PC client by default. If you want to switch regions, you need to change the `region` field in the Nebula config.
Current supported regions (PC): `GLOBAL`, `KR`, `JP`, `TW`
You may need to change the data version when switching regions. The `customDataVersion` field should match the the data version of your client, which is usually the last number of your client's version string (top left of your login screen). Example: 1.0.0.42 = data version 42.
# Running the server and client # Running the server and client
### Prerequisites ### Prerequisites
@@ -49,17 +57,24 @@ For any extra support, questions, or discussions, check out our [Discord](https:
3. Copy and paste the following code into the Fiddlerscript tab of Fiddler Classic. Remember to save the fiddler script after you copy and paste it: 3. Copy and paste the following code into the Fiddlerscript tab of Fiddler Classic. Remember to save the fiddler script after you copy and paste it:
``` ```
import System;
import System.Windows.Forms;
import Fiddler; import Fiddler;
import System.Text.RegularExpressions;
class Handlers class Handlers
{ {
static var list = [
".yostarplat.com",
".stellasora.global",
".stellasora.kr",
".stellasora.jp",
".stargazer-games.com"
];
static function OnBeforeRequest(oS: Session) { static function OnBeforeRequest(oS: Session) {
if (oS.host.EndsWith(".yostarplat.com") || oS.host.EndsWith(".stellasora.global")) { for (var i = 0; i < list.length; i++) {
oS.oRequest.headers.UriScheme = "http"; if (oS.host.EndsWith(list[i])) {
oS.host = "localhost"; // This can also be replaced with another IP address. oS.oRequest.headers.UriScheme = "http";
oS.host = "localhost"; // This can also be replaced with another IP address
}
} }
} }
}; };
@@ -68,14 +83,6 @@ class Handlers
4. If `autoCreateAccount` is set to true in the config, then you can skip this step. Otherwise, type `/account create [account email]` in the server console to create an account. 4. If `autoCreateAccount` is set to true in the config, then you can skip this step. Otherwise, type `/account create [account email]` in the server console to create an account.
5. Login with your account email, the code field is ignored by the server and can be set to anything. 5. Login with your account email, the code field is ignored by the server and can be set to anything.
If you are not on the global client, `.stellasora.global` in the fiddlerscript may need to be changed to match the endpoint your client connects to.
### Supported regions
Nebula supports the global client by default. If you want to switch regions, you need to change the `customDataVersion` and `region` fields in the Nebula config. The `customDataVersion` field should match the the data version of your client, which is usually the last number of your client's version string (top left of your login screen). Example: 1.0.0.42 = data version 42.
Current supported regions: `global`, `kr`
### Server commands ### Server commands
Server commands need to be run in the server console OR in the signature edit menu of your profile. Server commands need to be run in the server console OR in the signature edit menu of your profile.

View File

@@ -6,8 +6,23 @@ import emu.nebula.game.inventory.ItemParam;
import emu.nebula.util.WeightedList; import emu.nebula.util.WeightedList;
public class GameConstants { public class GameConstants {
private static final int DATA_VERSION = 60; public static final String VERSION = "1.2.0";
private static final String VERSION = "1.2.0"; public static int DATA_VERSION = 0;
// Set data versions for each region
static {
RegionConfig.getRegion("global")
.setDataVersion(60);
RegionConfig.getRegion("kr")
.setDataVersion(67);
RegionConfig.getRegion("jp")
.setDataVersion(63);
RegionConfig.getRegion("tw")
.setDataVersion(61);
}
public static final ZoneId UTC_ZONE = ZoneId.of("UTC"); public static final ZoneId UTC_ZONE = ZoneId.of("UTC");
@@ -57,7 +72,14 @@ public class GameConstants {
// Helper functions // Helper functions
public static String getGameVersion() { public static String getGameVersion() {
return VERSION + "." + getDataVersion() + " (" + Nebula.getConfig().getRegion().toUpperCase() + ")"; // Load data version
var region = RegionConfig.getRegion(Nebula.getConfig().getRegion());
// Set data version from region
GameConstants.DATA_VERSION = region.getDataVersion();
// Init game version string
return VERSION + "." + getDataVersion() + " (" + region.getName().toUpperCase() + ")";
} }
public static int getDataVersion() { public static int getDataVersion() {

View File

@@ -43,9 +43,8 @@ public class Nebula {
@Getter private static PluginManager pluginManager; @Getter private static PluginManager pluginManager;
public static void main(String[] args) { public static void main(String[] args) {
// Load config + keys first // Load config first
Nebula.loadConfig(); Nebula.loadConfig();
AeadHelper.loadKeys();
// Start Server // Start Server
Nebula.getLogger().info("Starting Nebula " + getJarVersion()); Nebula.getLogger().info("Starting Nebula " + getJarVersion());
@@ -54,6 +53,9 @@ public class Nebula {
boolean generateHandbook = true; boolean generateHandbook = true;
// Load keys
AeadHelper.loadKeys();
// Load plugin manager // Load plugin manager
Nebula.pluginManager = new PluginManager(); Nebula.pluginManager = new PluginManager();

View File

@@ -0,0 +1,42 @@
package emu.nebula;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import lombok.Getter;
import lombok.Setter;
@Getter @Setter
public class RegionConfig {
private String name;
private int dataVersion;
private String serverMetaKey;
private String serverGarbleKey;
private static Object2ObjectMap<String, RegionConfig> REGIONS = new Object2ObjectOpenHashMap<>();
public RegionConfig(String name) {
this.name = name;
this.serverMetaKey = "";
this.serverGarbleKey = "";
}
public RegionConfig setDataVersion(int i) {
this.dataVersion = i;
return this;
}
public RegionConfig setServerMetaKey(String key) {
this.serverMetaKey = key;
return this;
}
public RegionConfig setServerGarbleKey(String key) {
this.serverGarbleKey = key;
return this;
}
public static RegionConfig getRegion(String name) {
String regionName = name.toLowerCase();
return REGIONS.computeIfAbsent(regionName, r -> new RegionConfig(regionName));
}
}

View File

@@ -19,8 +19,7 @@ import org.bouncycastle.crypto.generators.HKDFBytesGenerator;
import org.bouncycastle.crypto.params.*; import org.bouncycastle.crypto.params.*;
import emu.nebula.Nebula; import emu.nebula.Nebula;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import emu.nebula.RegionConfig;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
// Official Name: AeadTool // Official Name: AeadTool
public class AeadHelper { public class AeadHelper {
@@ -34,29 +33,31 @@ public class AeadHelper {
public static byte[] serverGarbleKey = null; public static byte[] serverGarbleKey = null;
public static byte[] serverMetaKey = null; public static byte[] serverMetaKey = null;
private static final Object2ObjectMap<String, String[]> keys = new Object2ObjectOpenHashMap<>(); static {
RegionConfig.getRegion("global")
.setServerMetaKey("ma5Dn2FhC*Xhxy%c")
.setServerGarbleKey("xNdVF^XTa6T3HCUATMQ@sKMLzAw&%L!3");
RegionConfig.getRegion("kr")
.setServerMetaKey("U9cjHuwGDDx&$drn")
.setServerGarbleKey("25hdume9H#*6hHn@d9hSF7tekTwN#JYj");
RegionConfig.getRegion("jp")
.setServerMetaKey("ZnUFA@S9%4KyoryM")
.setServerGarbleKey("yX5Gt64PVvVH6$qwBXaPJC*LZKoK5mYh");
RegionConfig.getRegion("tw")
.setServerMetaKey("owGYVDmfHrxi^4pm")
.setServerGarbleKey("N&mfco452ZH5!nE3s&o5uxB57UGPENVo");
}
public static void loadKeys() { public static void loadKeys() {
// Load keys
keys.put("global", new String[] {
"ma5Dn2FhC*Xhxy%c",
"xNdVF^XTa6T3HCUATMQ@sKMLzAw&%L!3"
});
keys.put("kr", new String[] {
"U9cjHuwGDDx&$drn",
"25hdume9H#*6hHn@d9hSF7tekTwN#JYj"
});
// Get key data // Get key data
var keyData = keys.get(Nebula.getConfig().getRegion().toLowerCase()); var region = RegionConfig.getRegion(Nebula.getConfig().getRegion());
if (keyData == null) {
keyData = keys.get("global"); // Default region
}
// Set keys // Set keys
serverMetaKey = keyData[0].getBytes(StandardCharsets.US_ASCII); serverMetaKey = region.getServerMetaKey().getBytes(StandardCharsets.US_ASCII);
serverGarbleKey = keyData[1].getBytes(StandardCharsets.US_ASCII); serverGarbleKey = region.getServerGarbleKey().getBytes(StandardCharsets.US_ASCII);
} }
public static byte[] generateBytes(int size) { public static byte[] generateBytes(int size) {