Skip to content

Commit

Permalink
feat: move titles to classes rather than json
Browse files Browse the repository at this point in the history
having titles as classes rather than in a json file gives us the advantage of being able to set custom protocols on each title, such as protocol ID 200 which is shared between multiple games. It also lets us now define custom validation functions for packets in cases like LM2 and WATCH_DOGS which use non-standard checksum algorithms
  • Loading branch information
jonbarrow committed Feb 8, 2025
1 parent cb7406c commit 35a2ee2
Show file tree
Hide file tree
Showing 95 changed files with 2,790 additions and 2,344 deletions.
15 changes: 6 additions & 9 deletions src/nex/connection.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import settings from '@/settings';
import titles from '@/nex/titles';
import Substream from '@/nex/substream';
import RMCMessage from '@/nex/rmc-message';
import { keyDerivationOld, keyDerivationNew, Ticket } from '@/nex/kerberos';
import getProtocol from '@/nex/protocols/manager';
import TicketGrantingProtocol from '@/nex/protocols/ticket-granting';
import type Packet from '@/types/nex/packet';
import type StationURL from '@/nex/types/station-url';
import type { SerializedConnection, Title } from '@/types/nex/serialized-connection';

// TODO - Maybe this should be broken out into .ts files for each game? That way a game can define it's own signature calculation functions and such?
import titles from '@/nex/titles.json';

// * Represents an individual connection to a specific game server
export default class Connection {
public clientAddress: string;
Expand Down Expand Up @@ -107,13 +104,13 @@ export default class Connection {
if (!this.title) {
for (const title of titles) {
if (packet.version === -1) {
if (title.title_ids.includes(packet.titleID)) {
if (title.titleIDs.includes(packet.titleID)) {
this.title = title;
break;
}
} else if (packet.version === 0) {
const expectedChecksum = packet.checksum;
const calculatedChecksum = packet.calculateChecksum(title.access_key);
const calculatedChecksum = packet.calculateChecksum(title.accessKey);

if (expectedChecksum === calculatedChecksum) {
this.title = title;
Expand All @@ -123,7 +120,7 @@ export default class Connection {
// TODO - Legacy connection signature
const connectionSignature = packet.fromClientToServer ? this.clientConnectionSignature : this.serverConnectionSignature;
const expectedSignature = packet.signature;
const calculatedSignature = packet.calculateSignature(title.access_key, this.sessionKey, connectionSignature);
const calculatedSignature = packet.calculateSignature(title.accessKey, this.sessionKey, connectionSignature);

if (expectedSignature.equals(calculatedSignature)) {
this.title = title;
Expand All @@ -133,7 +130,7 @@ export default class Connection {
const serverAddress = packet.sourceAddress === 'CLIENT' ? packet.destinationAddress : packet.sourceAddress;
const gameServerID = serverAddress.split('-')[0].slice(1);

if (title.game_server_id === gameServerID) {
if (title.gameServerID === gameServerID) {
this.title = title;
break;
}
Expand Down Expand Up @@ -210,7 +207,7 @@ export default class Connection {
}
}

const protocol = getProtocol(packet.message);
const protocol = this.title.getProtocolHandler(packet.message);

if (protocol) {
packet.message.protocolName = protocol.Name;
Expand Down
38 changes: 0 additions & 38 deletions src/nex/protocols/manager.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default class AutoMatchmakeParam extends Structure {
this.lstSearchCriteria.extractFrom(stream);
this.targetGids.extractFrom(stream);

if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=4.0.0')) {
this.blockListParam = new MatchmakeBlockListParam();
this.blockListParam.extractFrom(stream);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ export default class JoinMatchmakeSessionParam extends Structure {
this.joinMessage.extractFrom(stream);
this.participationCount.extractFrom(stream);

if (this.structureVersion >= 1 || semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) {
if (this.structureVersion >= 1 || semver.satisfies(stream.title.libraryVersions.match_making, '>=4.0.0')) {
this.extraParticipants = new UInt16();
this.extraParticipants.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=4.0.0')) {
this.blockListParam = new MatchmakeBlockListParam();
this.blockListParam.extractFrom(stream);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default class MatchmakeSessionSearchCriteria extends Structure {
this.m_Attribs.extractFrom(stream);
this.m_GameMode.extractFrom(stream);

if (semver.satisfies(stream.title.library_versions.match_making, '>=2.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=2.0.0')) {
this.m_MinParticipants = new RVString();
this.m_MaxParticipants = new RVString();

Expand All @@ -48,35 +48,35 @@ export default class MatchmakeSessionSearchCriteria extends Structure {
this.m_ExcludeLocked.extractFrom(stream);
this.m_ExcludeNonHostPid.extractFrom(stream);

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.0.0')) {
this.m_SelectionMethod = new UInt32();
this.m_SelectionMethod.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.4.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.4.0')) {
this.m_VacantParticipants = new UInt16();
this.m_VacantParticipants.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.6.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.6.0')) {
this.m_MatchmakeParam = new MatchmakeParam();
this.m_MatchmakeParam.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.7.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.7.0')) {
this.m_ExcludeUserPasswordSet = new Bool();
this.m_ExcludeSystemPasswordSet = new Bool();

this.m_ExcludeUserPasswordSet.extractFrom(stream);
this.m_ExcludeSystemPasswordSet.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.8.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.8.0')) {
this.m_ReferGid = new UInt32();
this.m_ReferGid.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=4.0.0')) {
this.m_Codeword = new RVString();
this.m_ResultRange = new ResultRange();

Expand Down
14 changes: 7 additions & 7 deletions src/nex/protocols/match-making/types/matchmake-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,35 +45,35 @@ export default class MatchmakeSession extends Gathering {
this.m_ApplicationBuffer.extractFrom(stream);
this.m_ParticipationCount.extractFrom(stream);

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.4.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.4.0')) {
this.m_ProgressScore = new UInt8();
this.m_ProgressScore.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.0.0')) {
this.m_SessionKey = new RVBuffer();
this.m_SessionKey.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.5.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.5.0')) {
this.m_Option0 = new UInt32();
this.m_Option0.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.6.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.6.0')) {
this.m_MatchmakeParam = new MatchmakeParam();
this.m_StartedTime = new DateTime();

this.m_MatchmakeParam.extractFrom(stream);
this.m_StartedTime.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.7.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.7.0')) {
this.m_UserPassword = new RVString();
this.m_UserPassword.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.8.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.8.0')) {
this.m_ReferGid = new UInt32();
this.m_UserPasswordEnabled = new Bool();
this.m_SystemPasswordEnabled = new Bool();
Expand All @@ -83,7 +83,7 @@ export default class MatchmakeSession extends Gathering {
this.m_SystemPasswordEnabled.extractFrom(stream);
}

if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=4.0.0')) {
this.m_Codeword = new RVString();
this.m_Codeword.extractFrom(stream);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Request {
this.anyGathering.extractFrom(stream);
this.strMessage.extractFrom(stream);

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.4.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.4.0')) {
this.participationCount = new UInt16();
this.participationCount.extractFrom(stream);
}
Expand Down Expand Up @@ -53,7 +53,7 @@ export class Response {

this.gid.extractFrom(stream);

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.0.0')) {
this.sessionKey = new RVBuffer();
this.sessionKey.extractFrom(stream);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class Request {
this.strMessage.extractFrom(stream);
this.dontCareMyBlackList.extractFrom(stream);

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.4.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.4.0')) {
this.participationCount = new UInt16();
this.participationCount.extractFrom(stream);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class Response {
constructor(message: RMCMessage) {
const stream = new NEXByteStream(message.parametersData!, message.connection.title);

if (semver.satisfies(stream.title.library_versions.match_making, '>=3.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=3.0.0')) {
this.sessionKey = new RVBuffer();
this.sessionKey.extractFrom(stream);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class Request {
constructor(message: RMCMessage) {
const stream = new NEXByteStream(message.parametersData!, message.connection.title);

if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) {
if (semver.satisfies(stream.title.libraryVersions.match_making, '>=4.0.0')) {
this.uiParam1 = new UInt64();
this.uiParam2 = new UInt64();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default class NotificationEvent extends Structure {
this.m_uiParam2.extractFrom(stream);
this.m_strParam.extractFrom(stream);

if (semver.satisfies(stream.title.library_versions.main, '>=3.4.0')) {
if (semver.satisfies(stream.title.libraryVersions.main, '>=3.4.0')) {
this.m_uiParam3 = new UInt32();
this.m_uiParam3.extractFrom(stream);
}
Expand Down
Loading

0 comments on commit 35a2ee2

Please sign in to comment.