implement GC Ep1&2 trial edition
This commit is contained in:
@@ -51,6 +51,9 @@ struct Client {
|
||||
ENCRYPTED_SEND_FUNCTION_CALL = 0x0800,
|
||||
// Client supports send_function_call but does not actually run the code
|
||||
SEND_FUNCTION_CALL_CHECKSUM_ONLY = 0x1000,
|
||||
// Client is GC Trial Edition, and therefore uses V2 encryption instead of
|
||||
// V3, and doesn't support some commands
|
||||
GC_TRIAL_EDITION = 0x2000,
|
||||
};
|
||||
|
||||
uint64_t id;
|
||||
|
||||
+34
-21
@@ -376,8 +376,10 @@ struct C_LegacyLogin_BB_04 {
|
||||
// 05 = Server down for maintenance (108)
|
||||
// 06 = Incorrect password (127)
|
||||
// Any other nonzero value = Generic failure (101)
|
||||
// The client config field in this command is only used by V3 clients. newserv
|
||||
// sends it anyway to clients on earlier versions, but they ignore it.
|
||||
// The client config field in this command is ignored by pre-V3 clients as well
|
||||
// as Episodes 1&2 Trial Edition. All other V3 clients save it as opaque data to
|
||||
// be returned in a 9E or 9F command later. newserv sends the client config
|
||||
// anyway to clients that ignore it.
|
||||
// Client will respond with a 96 command, but only the first time it receives
|
||||
// this command - for later 04 commands, the client will still update its client
|
||||
// config but will not respond. Changing the security data at any time seems ok,
|
||||
@@ -433,8 +435,8 @@ struct S_MenuEntry {
|
||||
le_uint16_t flags; // should be 0x0F04
|
||||
ptext<CharT, EntryLength> text;
|
||||
};
|
||||
struct S_MenuEntry_PC_BB_07_1F : S_MenuEntry<char16_t, 17> { };
|
||||
struct S_MenuEntry_DC_V3_07_1F : S_MenuEntry<char, 18> { };
|
||||
struct S_MenuEntry_PC_BB_07_1F : S_MenuEntry<char16_t, 0x11> { };
|
||||
struct S_MenuEntry_DC_V3_07_1F : S_MenuEntry<char, 0x12> { };
|
||||
|
||||
// 08 (C->S): Request game list
|
||||
// No arguments
|
||||
@@ -578,8 +580,9 @@ struct C_WriteFileConfirmation_V3_BB_13_A7 {
|
||||
// All commands after this command will be encrypted with PSO V2 encryption on
|
||||
// PC, or PSO V3 encryption on V3.
|
||||
// V3 clients will respond with a DB command the first time they receive a 17
|
||||
// command in any online session; after the first time, they will respond with a
|
||||
// 9E. Non-V3 clients will respond with a 9D.
|
||||
// command in any online session, with the exception of Episodes 1&2 trial
|
||||
// edition (which responds with a 9A). After the first time, V3 clients will
|
||||
// respond with a 9E. Non-V3 clients will respond with a 9D.
|
||||
// The copyright field in the structure must contain the following text:
|
||||
// "DreamCast Port Map. Copyright SEGA Enterprises. 1999"
|
||||
|
||||
@@ -1307,8 +1310,9 @@ struct C_Register_BB_9C {
|
||||
// displayed if the header.flag field is zero. If header.flag is nonzero, the
|
||||
// client proceeds with the login procedure by sending a 9D/9E.
|
||||
|
||||
// 9D (C->S): Log in without client config (PC)
|
||||
// Not used on V3 - the client sends 9E instead.
|
||||
// 9D (C->S): Log in without client config (PC/GC)
|
||||
// Not used on most versions of V3 - the client sends 9E instead. The one
|
||||
// type of PSO V3 that uses 9D is the Trial Edition of Episodes 1&2.
|
||||
// The extended version of this command is sent if the client has not yet
|
||||
// received an 04 (in which case the extended fields are blank) or if the client
|
||||
// selected the Meet User option, in which case it specifies the requested lobby
|
||||
@@ -1322,7 +1326,7 @@ struct C_Login_MeetUserExtension {
|
||||
ptext<CharT, 0x20> target_player_name;
|
||||
};
|
||||
|
||||
struct C_Login_PC_9D {
|
||||
struct C_Login_PC_GC_9D {
|
||||
le_uint32_t player_tag; // 0x00010000 if guild card is set (via 04)
|
||||
le_uint32_t guild_card_number; // 0xFFFFFFFF if not set
|
||||
le_uint64_t unused;
|
||||
@@ -1338,7 +1342,7 @@ struct C_Login_PC_9D {
|
||||
ptext<char, 0x30> access_key2; // On XB, this is the XBL user ID
|
||||
ptext<char, 0x10> name;
|
||||
};
|
||||
struct C_LoginExtended_PC_9D : C_Login_PC_9D {
|
||||
struct C_LoginExtended_PC_GC_9D : C_Login_PC_GC_9D {
|
||||
C_Login_MeetUserExtension<char16_t> extension;
|
||||
};
|
||||
|
||||
@@ -1346,7 +1350,7 @@ struct C_LoginExtended_PC_9D : C_Login_PC_9D {
|
||||
// The extended version of this command is used in the same circumstances as
|
||||
// when PSO PC uses the extended version of the 9D command.
|
||||
|
||||
struct C_Login_GC_9E : C_Login_PC_9D {
|
||||
struct C_Login_GC_9E : C_Login_PC_GC_9D {
|
||||
union ClientConfigFields {
|
||||
ClientConfig cfg;
|
||||
parray<uint8_t, 0x20> data;
|
||||
@@ -1383,6 +1387,8 @@ struct C_LoginExtended_BB_9E {
|
||||
};
|
||||
|
||||
// 9F (S->C): Request client config / security data (V3/BB)
|
||||
// This command is not valid on PSO GC Episodes 1&2 Trial Edition, nor any
|
||||
// pre-V3 PSO versions.
|
||||
// No arguments
|
||||
|
||||
// 9F (C->S): Client config / security data response (V3/BB)
|
||||
@@ -1476,6 +1482,8 @@ struct S_QuestMenuEntry_BB_A2_A4 : S_QuestMenuEntry<char16_t, 0x7A> { };
|
||||
// specific to that quest. The structure here represents the only instance I've
|
||||
// seen so far.
|
||||
// The server will respond with an AB command.
|
||||
// This command is likely never sent by PSO GC Episodes 1&2 Trial Edition,
|
||||
// because the following command (AB) is definitely not valid on that version.
|
||||
|
||||
struct C_UpdateQuestStatistics_AA {
|
||||
le_uint16_t quest_internal_id;
|
||||
@@ -1489,6 +1497,7 @@ struct C_UpdateQuestStatistics_AA {
|
||||
};
|
||||
|
||||
// AB (S->C): Confirm update quest statistics
|
||||
// This command is not valid on PSO GC Episodes 1&2 Trial Edition.
|
||||
// TODO: Does this command have a different meaning in Episode 3? Is it used at
|
||||
// all there, or is the handler an undeleted vestige from Episodes 1&2?
|
||||
|
||||
@@ -1508,6 +1517,7 @@ struct S_ConfirmUpdateQuestStatistics_AB {
|
||||
// which starts the quest for all players at (approximately) the same time.
|
||||
// Sending this command to a GC client when it is not waiting to start a quest
|
||||
// will cause it to crash.
|
||||
// This command is not valid on PSO GC Episodes 1&2 Trial Edition.
|
||||
|
||||
// AD: Invalid command
|
||||
// AE: Invalid command
|
||||
@@ -1939,6 +1949,7 @@ struct C_GBAGameRequest_V3_D7 {
|
||||
|
||||
// D7 (S->C): Unknown (V3/BB)
|
||||
// No arguments
|
||||
// This command is not valid on PSO GC Episodes 1&2 Trial Edition.
|
||||
// On PSO V3, this command does... something. The command isn't *completely*
|
||||
// ignored: it sets a global state variable, but it's not clear what that
|
||||
// variable does. That variable is also set when a D7 is sent by the client, so
|
||||
@@ -1950,6 +1961,7 @@ struct C_GBAGameRequest_V3_D7 {
|
||||
// The server should respond with a D8 command (described below).
|
||||
|
||||
// D8 (S->C): Info board contents (V3/BB)
|
||||
// This command is not valid on PSO GC Episodes 1&2 Trial Edition.
|
||||
|
||||
// Command is a list of these; header.flag is the entry count. There should be
|
||||
// one entry for each player in the current lobby/game.
|
||||
@@ -1967,6 +1979,7 @@ struct S_InfoBoardEntry_V3_D8 : S_InfoBoardEntry_D8<char> { };
|
||||
|
||||
// DA (S->C): Change lobby event (V3/BB)
|
||||
// header.flag = new event number; no other arguments.
|
||||
// This command is not valid on PSO GC Episodes 1&2 Trial Edition.
|
||||
|
||||
// DB (C->S): Verify license (V3/BB)
|
||||
// Server should respond with a 9A command.
|
||||
@@ -3007,10 +3020,10 @@ struct G_EnemyDropItemRequest_6x60 {
|
||||
// 68: Telepipe/Ryuker
|
||||
// 69: Unknown (supported; game only)
|
||||
// 6A: Unknown (supported; game only; not valid on Episode 3)
|
||||
// 6B: Unknown (used while loading into game)
|
||||
// 6C: Unknown (used while loading into game)
|
||||
// 6D: Unknown (used while loading into game)
|
||||
// 6E: Unknown (used while loading into game)
|
||||
// 6B: Sync enemy state (used while loading into game)
|
||||
// 6C: Sync object state (used while loading into game)
|
||||
// 6D: Sync item state (used while loading into game)
|
||||
// 6E: Sync flag state (used while loading into game)
|
||||
// 6F: Unknown (used while loading into game)
|
||||
// 70: Unknown (used while loading into game)
|
||||
// 71: Unknown (used while loading into game)
|
||||
@@ -3087,12 +3100,12 @@ struct G_BoxItemDropRequest_6xA2 {
|
||||
// AA: Episode 2 boss actions (not valid on PC or Episode 3)
|
||||
// AB: Create lobby chair (not valid on PC)
|
||||
// AC: Unknown (not valid on PC)
|
||||
// AD: Unknown (not valid on PC or Episode 3)
|
||||
// AE: Set chair state? (sent by existing clients at join time; not valid on PC)
|
||||
// AF: Turn in lobby chair (not valid on PC)
|
||||
// B0: Move in lobby chair (not valid on PC)
|
||||
// B1: Unknown (not valid on PC)
|
||||
// B2: Unknown (not valid on PC)
|
||||
// AD: Unknown (not valid on PC, Episode 3, or GC Trial Edition)
|
||||
// AE: Set chair state? (sent by existing clients at join time; not valid on PC or GC Trial Edition)
|
||||
// AF: Turn in lobby chair (not valid on PC or GC Trial Edition)
|
||||
// B0: Move in lobby chair (not valid on PC or GC Trial Edition)
|
||||
// B1: Unknown (not valid on PC or GC Trial Edition)
|
||||
// B2: Unknown (not valid on PC or GC Trial Edition)
|
||||
// B3: Unknown (Episode 3 only)
|
||||
// B4: Unknown (Episode 3 only)
|
||||
// B5: Episode 3 game setup menu state sync
|
||||
|
||||
@@ -217,7 +217,7 @@ static HandlerResult process_server_pc_v3_patch_02_17(shared_ptr<ServerState> s,
|
||||
return HandlerResult::Type::SUPPRESS;
|
||||
|
||||
} else if (session.version == GameVersion::PC) {
|
||||
C_Login_PC_9D cmd;
|
||||
C_Login_PC_GC_9D cmd;
|
||||
if (session.remote_guild_card_number == 0) {
|
||||
cmd.player_tag = 0xFFFF0000;
|
||||
cmd.guild_card_number = 0xFFFFFFFF;
|
||||
|
||||
+2
-2
@@ -269,8 +269,8 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3
|
||||
if (command != 0x9D) {
|
||||
throw runtime_error("command is not 9D");
|
||||
}
|
||||
const auto& cmd = check_size_t<C_Login_PC_9D>(
|
||||
data, sizeof(C_Login_PC_9D), sizeof(C_LoginExtended_PC_9D));
|
||||
const auto& cmd = check_size_t<C_Login_PC_GC_9D>(
|
||||
data, sizeof(C_Login_PC_GC_9D), sizeof(C_LoginExtended_PC_GC_9D));
|
||||
license = session->server->state->license_manager->verify_pc(
|
||||
stoul(cmd.serial_number, nullptr, 16), cmd.access_key);
|
||||
sub_version = cmd.sub_version;
|
||||
|
||||
+25
-10
@@ -76,6 +76,9 @@ void process_connect(std::shared_ptr<ServerState> s, std::shared_ptr<Client> c)
|
||||
break;
|
||||
}
|
||||
|
||||
case ServerBehavior::LOGIN_SERVER_GC_TRIAL_EDITION:
|
||||
c->flags |= Client::Flag::GC_TRIAL_EDITION;
|
||||
[[fallthrough]];
|
||||
case ServerBehavior::LOGIN_SERVER:
|
||||
send_server_init(s, c, true, false);
|
||||
if (s->pre_lobby_event) {
|
||||
@@ -85,6 +88,11 @@ void process_connect(std::shared_ptr<ServerState> s, std::shared_ptr<Client> c)
|
||||
|
||||
case ServerBehavior::PATCH_SERVER_BB:
|
||||
c->flags |= Client::Flag::BB_PATCH;
|
||||
send_server_init(s, c, false, false);
|
||||
break;
|
||||
|
||||
case ServerBehavior::LOBBY_SERVER_GC_TRIAL_EDITION:
|
||||
c->flags |= Client::Flag::GC_TRIAL_EDITION;
|
||||
[[fallthrough]];
|
||||
case ServerBehavior::PATCH_SERVER_PC:
|
||||
case ServerBehavior::DATA_SERVER_BB:
|
||||
@@ -319,12 +327,12 @@ void process_login_d_e_pc_v3(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||
// The client sends extra unused data the first time it sends these commands,
|
||||
// hence the odd check_size calls here
|
||||
|
||||
const C_Login_PC_9D* base_cmd;
|
||||
const C_Login_PC_GC_9D* base_cmd;
|
||||
if (command == 0x9D) {
|
||||
base_cmd = &check_size_t<C_Login_PC_9D>(data,
|
||||
sizeof(C_Login_PC_9D), sizeof(C_LoginExtended_PC_9D));
|
||||
base_cmd = &check_size_t<C_Login_PC_GC_9D>(data,
|
||||
sizeof(C_Login_PC_GC_9D), sizeof(C_LoginExtended_PC_GC_9D));
|
||||
if (base_cmd->is_extended) {
|
||||
const auto& cmd = check_size_t<C_LoginExtended_PC_9D>(data);
|
||||
const auto& cmd = check_size_t<C_LoginExtended_PC_GC_9D>(data);
|
||||
if (cmd.extension.menu_id == MenuID::LOBBY) {
|
||||
c->preferred_lobby_id = cmd.extension.preferred_lobby_id;
|
||||
}
|
||||
@@ -1119,12 +1127,15 @@ void process_menu_selection(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||
send_quest_file(l->clients[x], dat_basename + ".dat", dat_basename,
|
||||
*dat_contents, QuestFileType::ONLINE);
|
||||
|
||||
// There is no such thing as command AC on PSO PC - quests just start
|
||||
// immediately when they're done downloading. There are also no chunk
|
||||
// acknowledgements (C->S 13 commands) like there are on GC. So, for
|
||||
// PC clients, we can just not set the loading flag, since we never
|
||||
// need to check/clear it later.
|
||||
if (l->clients[x]->version != GameVersion::PC) {
|
||||
// There is no such thing as command AC on PSO V2 - quests just start
|
||||
// immediately when they're done downloading. (This is also the case
|
||||
// on V3 Trial Edition.) There are also no chunk acknowledgements
|
||||
// (C->S 13 commands) like there are on GC. So, for PC/Trial clients,
|
||||
// we can just not set the loading flag, since we never need to
|
||||
// check/clear it later.
|
||||
if ((l->clients[x]->version != GameVersion::DC) &&
|
||||
(l->clients[x]->version != GameVersion::PC) &&
|
||||
!(l->clients[x]->flags & Client::Flag::GC_TRIAL_EDITION)) {
|
||||
l->clients[x]->flags |= Client::Flag::LOADING_QUEST;
|
||||
}
|
||||
}
|
||||
@@ -1407,6 +1418,10 @@ void process_update_quest_statistics(shared_ptr<ServerState> s,
|
||||
shared_ptr<Client> c, uint16_t, uint32_t, const string& data) { // AA
|
||||
const auto& cmd = check_size_t<C_UpdateQuestStatistics_AA>(data);
|
||||
|
||||
if (c->flags & Client::Flag::GC_TRIAL_EDITION) {
|
||||
throw runtime_error("trial edition client sent update quest stats command");
|
||||
}
|
||||
|
||||
auto l = s->find_lobby(c->lobby_id);
|
||||
if (!l || !l->is_game() || !l->loading_quest.get() ||
|
||||
(l->loading_quest->internal_id != cmd.quest_internal_id)) {
|
||||
|
||||
@@ -105,8 +105,8 @@ void ReplaySession::check_for_password(shared_ptr<const Event> ev) const {
|
||||
check_ak(cmd.access_key);
|
||||
check_pw(cmd.password);
|
||||
} else if (header.command == 0x9D) {
|
||||
const auto& cmd = check_size_t<C_Login_PC_9D>(cmd_data, cmd_size,
|
||||
sizeof(C_Login_PC_9D), sizeof(C_LoginExtended_PC_9D));
|
||||
const auto& cmd = check_size_t<C_Login_PC_GC_9D>(cmd_data, cmd_size,
|
||||
sizeof(C_Login_PC_GC_9D), sizeof(C_LoginExtended_PC_GC_9D));
|
||||
check_ak(cmd.access_key);
|
||||
check_ak(cmd.access_key2);
|
||||
}
|
||||
|
||||
+14
-9
@@ -104,8 +104,7 @@ S_ServerInit_DC_PC_V3_02_17_91_9B prepare_server_init_contents_dc_pc_v3(
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void send_server_init_dc_pc_v3(shared_ptr<Client> c,
|
||||
bool initial_connection) {
|
||||
void send_server_init_dc_pc_v3(shared_ptr<Client> c, bool initial_connection) {
|
||||
uint8_t command = initial_connection ? 0x17 : 0x02;
|
||||
uint32_t server_key = random_object<uint32_t>();
|
||||
uint32_t client_key = random_object<uint32_t>();
|
||||
@@ -122,8 +121,13 @@ void send_server_init_dc_pc_v3(shared_ptr<Client> c,
|
||||
break;
|
||||
case GameVersion::GC:
|
||||
case GameVersion::XB:
|
||||
c->channel.crypt_out.reset(new PSOV3Encryption(server_key));
|
||||
c->channel.crypt_in.reset(new PSOV3Encryption(client_key));
|
||||
if (c->flags & Client::Flag::GC_TRIAL_EDITION) {
|
||||
c->channel.crypt_out.reset(new PSOV2Encryption(server_key));
|
||||
c->channel.crypt_in.reset(new PSOV2Encryption(client_key));
|
||||
} else {
|
||||
c->channel.crypt_out.reset(new PSOV3Encryption(server_key));
|
||||
c->channel.crypt_in.reset(new PSOV3Encryption(client_key));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw invalid_argument("incorrect client version");
|
||||
@@ -1584,12 +1588,13 @@ void send_server_time(shared_ptr<Client> c) {
|
||||
}
|
||||
|
||||
void send_change_event(shared_ptr<Client> c, uint8_t new_event) {
|
||||
// THis command isn't supported on versions before V3
|
||||
if ((c->version == GameVersion::GC) ||
|
||||
(c->version == GameVersion::XB) ||
|
||||
(c->version == GameVersion::BB)) {
|
||||
send_command(c, 0xDA, new_event);
|
||||
// This command isn't supported on versions before V3, nor on Trial Edition.
|
||||
if ((c->version == GameVersion::DC) ||
|
||||
(c->version == GameVersion::PC) ||
|
||||
(c->flags & Client::Flag::GC_TRIAL_EDITION)) {
|
||||
return;
|
||||
}
|
||||
send_command(c, 0xDA, new_event);
|
||||
}
|
||||
|
||||
void send_change_event(shared_ptr<Lobby> l, uint8_t new_event) {
|
||||
|
||||
@@ -39,6 +39,10 @@ uint16_t flags_for_version(GameVersion version, int64_t sub_version) {
|
||||
return Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION |
|
||||
Client::Flag::SEND_FUNCTION_CALL_CHECKSUM_ONLY;
|
||||
|
||||
// TODO: GC Ep1&2 trial edition uses sub_version 0x30, but also uses PSO V2
|
||||
// encryption! Find a way to tell that version apart from the others before
|
||||
// starting encryption (hopefully it connects on a port not shared by other
|
||||
// versions).
|
||||
case 0x30: // GC Ep1&2 JP v1.02, at least one version of PSO XB
|
||||
case 0x31: // GC Ep1&2 US v1.00, GC US v1.01, GC EU v1.00, GC JP v1.00
|
||||
case 0x34: // GC Ep1&2 JP v1.03
|
||||
@@ -114,8 +118,12 @@ const char* name_for_server_behavior(ServerBehavior behavior) {
|
||||
return "split_reconnect";
|
||||
case ServerBehavior::LOGIN_SERVER:
|
||||
return "login_server";
|
||||
case ServerBehavior::LOGIN_SERVER_GC_TRIAL_EDITION:
|
||||
return "login_server_gcte";
|
||||
case ServerBehavior::LOBBY_SERVER:
|
||||
return "lobby_server";
|
||||
case ServerBehavior::LOBBY_SERVER_GC_TRIAL_EDITION:
|
||||
return "lobby_server_gcte";
|
||||
case ServerBehavior::DATA_SERVER_BB:
|
||||
return "data_server_bb";
|
||||
case ServerBehavior::PATCH_SERVER_PC:
|
||||
@@ -134,8 +142,12 @@ ServerBehavior server_behavior_for_name(const char* name) {
|
||||
return ServerBehavior::SPLIT_RECONNECT;
|
||||
} else if (!strcasecmp(name, "login_server") || !strcasecmp(name, "login")) {
|
||||
return ServerBehavior::LOGIN_SERVER;
|
||||
} else if (!strcasecmp(name, "login_server_gcte") || !strcasecmp(name, "login_gcte")) {
|
||||
return ServerBehavior::LOGIN_SERVER_GC_TRIAL_EDITION;
|
||||
} else if (!strcasecmp(name, "lobby_server") || !strcasecmp(name, "lobby")) {
|
||||
return ServerBehavior::LOBBY_SERVER;
|
||||
} else if (!strcasecmp(name, "lobby_server_gcte") || !strcasecmp(name, "lobby_gcte")) {
|
||||
return ServerBehavior::LOBBY_SERVER_GC_TRIAL_EDITION;
|
||||
} else if (!strcasecmp(name, "data_server_bb") || !strcasecmp(name, "data_server") || !strcasecmp(name, "data")) {
|
||||
return ServerBehavior::DATA_SERVER_BB;
|
||||
} else if (!strcasecmp(name, "patch_server_pc") || !strcasecmp(name, "patch_pc")) {
|
||||
|
||||
@@ -16,7 +16,9 @@ enum class GameVersion {
|
||||
enum class ServerBehavior {
|
||||
SPLIT_RECONNECT = 0,
|
||||
LOGIN_SERVER,
|
||||
LOGIN_SERVER_GC_TRIAL_EDITION,
|
||||
LOBBY_SERVER,
|
||||
LOBBY_SERVER_GC_TRIAL_EDITION,
|
||||
DATA_SERVER_BB,
|
||||
PATCH_SERVER_PC,
|
||||
PATCH_SERVER_BB,
|
||||
|
||||
@@ -23,14 +23,19 @@
|
||||
|
||||
// Various versions of PSO hardcode these ports in the clients. Don't change
|
||||
// these unless you don't want to support certain versions of PSO.
|
||||
// TODO: GC Episodes 1&2 Trial Edition also uses port 9000, but a real
|
||||
// version of PSO uses that port too. Figure out a way to differentiate
|
||||
// between the two versions.
|
||||
"gc-jp10": [9000, "gc", "login_server"],
|
||||
"gc-jp11": [9001, "gc", "login_server"],
|
||||
"gc-jpte": [9002, "gc", "login_server"],
|
||||
"gc-jp3te": [9002, "gc", "login_server"],
|
||||
"gc-jp3": [9003, "gc", "login_server"],
|
||||
"gc-us12t1": [9064, "gc", "login_server_gcte"],
|
||||
"gc-us10": [9100, "pc", "split_reconnect"],
|
||||
"gc-us3": [9103, "gc", "login_server"],
|
||||
"gc-eu10": [9200, "gc", "login_server"],
|
||||
"gc-eu11": [9201, "gc", "login_server"],
|
||||
"gc-us12t2": [9202, "gc", "login_server_gcte"],
|
||||
"gc-eu3": [9203, "gc", "login_server"],
|
||||
"pc-login": [9300, "pc", "login_server"],
|
||||
"pc-patch": [10000, "patch", "patch_server_pc"],
|
||||
@@ -60,10 +65,12 @@
|
||||
"gc-lobby": [9421, "gc", "lobby_server"],
|
||||
"bb-lobby": [9422, "bb", "lobby_server"],
|
||||
"xb-lobby": [9423, "xb", "lobby_server"],
|
||||
"gct-lobby": [9424, "gc", "lobby_server_gcte"],
|
||||
"pc-proxy": [9520, "pc", "proxy_server"],
|
||||
"gc-proxy": [9521, "gc", "proxy_server"],
|
||||
"bb-proxy": [9522, "bb", "proxy_server"],
|
||||
"xb-proxy": [9523, "xb", "proxy_server"],
|
||||
// TODO: Implement proxy server for GC Trial Edition
|
||||
"bb-data1": [12004, "bb", "data_server_bb"],
|
||||
"bb-data2": [12005, "bb", "data_server_bb"],
|
||||
},
|
||||
|
||||
+6
-1
@@ -19,12 +19,14 @@
|
||||
"PortConfiguration": {
|
||||
"gc-jp10": [9000, "gc", "login_server"],
|
||||
"gc-jp11": [9001, "gc", "login_server"],
|
||||
"gc-jpte": [9002, "gc", "login_server"],
|
||||
"gc-jp3te": [9002, "gc", "login_server"],
|
||||
"gc-jp3": [9003, "gc", "login_server"],
|
||||
"gc-us12t1": [9064, "gc", "login_server_gcte"],
|
||||
"gc-us10": [9100, "pc", "split_reconnect"],
|
||||
"gc-us3": [9103, "gc", "login_server"],
|
||||
"gc-eu10": [9200, "gc", "login_server"],
|
||||
"gc-eu11": [9201, "gc", "login_server"],
|
||||
"gc-us12t2": [9202, "gc", "login_server_gcte"],
|
||||
"gc-eu3": [9203, "gc", "login_server"],
|
||||
"pc-login": [9300, "pc", "login_server"],
|
||||
"pc-patch": [10000, "patch", "patch_server_pc"],
|
||||
@@ -38,9 +40,12 @@
|
||||
"pc-lobby": [9420, "pc", "lobby_server"],
|
||||
"gc-lobby": [9421, "gc", "lobby_server"],
|
||||
"bb-lobby": [9422, "bb", "lobby_server"],
|
||||
"xb-lobby": [9423, "xb", "lobby_server"],
|
||||
"gct-lobby": [9424, "gc", "lobby_server_gcte"],
|
||||
"pc-proxy": [9520, "pc", "proxy_server"],
|
||||
"gc-proxy": [9521, "gc", "proxy_server"],
|
||||
"bb-proxy": [9522, "bb", "proxy_server"],
|
||||
"xb-proxy": [9523, "xb", "proxy_server"],
|
||||
},
|
||||
|
||||
"ProxyDestinations-GC": {
|
||||
|
||||
Reference in New Issue
Block a user