Skip to content

Commit

Permalink
Support for Properties
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrianCassar committed Feb 2, 2025
1 parent ad1e7da commit b5a8c1c
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class AddSessionPropertyCommandHandler
return undefined;
}

session.addProperty({ property: command.properties });
session.addProperties({ properties: command.properties });
await this.repository.save(session);

return session;
Expand Down
6 changes: 2 additions & 4 deletions src/application/commands/AddSessionPropertyCommand.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import Property from 'src/domain/value-objects/Property';
import SessionId from 'src/domain/value-objects/SessionId';
import TitleId from 'src/domain/value-objects/TitleId';

export class AddSessionPropertyCommand {
constructor(
public readonly titleId: TitleId,
public readonly sessionId: SessionId,
public readonly properties: Map<
number,
{ propertyId: number; value: number }
>,
public readonly properties: Array<Property>,
) {}
}
2 changes: 1 addition & 1 deletion src/application/queryHandlers/SessionSearchQueryHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class SessionSearchQueryHandler
}

async execute(query: SessionSearchQuery) {
this.logger.debug('Session Search ' + query.searchIndex);
this.logger.verbose(`Matchmaking Query ID: ${query.searchIndex}`);

return this.repository.findAdvertisedSessions(
query.title,
Expand Down
40 changes: 34 additions & 6 deletions src/domain/aggregates/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import SessionFlags from '../value-objects/SessionFlags';
import SessionId from '../value-objects/SessionId';
import TitleId from '../value-objects/TitleId';
import Xuid from '../value-objects/Xuid';
import Property from '../value-objects/Property';

interface SessionProps {
id: SessionId;
Expand All @@ -22,7 +23,7 @@ interface SessionProps {
players: Map<string, boolean>;
deleted: boolean;
context: Map<string, number>;
properties: Map<string, number>;
properties: Array<Property>;
migration?: SessionId;
}

Expand Down Expand Up @@ -59,7 +60,7 @@ interface ContextProps {
context: Map<number, { contextId: number; value: number }>;
}
interface PropertyProps {
property: Map<number, { propertyId: number; value: number }>;
properties: Array<Property>;
}
interface JoinProps {
members: Map<Xuid, boolean>;
Expand All @@ -69,6 +70,9 @@ interface LeaveProps {
xuids: Xuid[];
}

const X_PROPERTY_GAMER_HOSTNAME = 0x40008109;
const X_PROPERTY_GAMER_PUID = 0x20008107;

export default class Session {
private readonly props: SessionProps;

Expand Down Expand Up @@ -104,7 +108,7 @@ export default class Session {
players: new Map<string, boolean>(),
deleted: false,
context: new Map<string, number>(),
properties: new Map<string, number>(),
properties: new Array<Property>(),
});
}

Expand Down Expand Up @@ -153,9 +157,9 @@ export default class Session {
});
}

public addProperty(props: PropertyProps) {
props.property.forEach((entry) => {
this.props.properties.set(entry.propertyId.toString(16), entry.value);
public addProperties(props: PropertyProps) {
props.properties.forEach((entry) => {
this.props.properties.push(entry);
});
}

Expand Down Expand Up @@ -352,4 +356,28 @@ export default class Session {
get properties() {
return this.props.properties;
}

get propertiesStringArray() {
const properties: Array<string> = this.props.properties.map((prop) => {
return prop.toString();
});

return properties;
}

get propertyHostGamerName() {
const GAMER_HOSTNAME = this.props.properties.find((prop) => {
return prop.id == X_PROPERTY_GAMER_HOSTNAME;
});

return GAMER_HOSTNAME;
}

get propertyPUID() {
const PUID = this.props.properties.find((prop) => {
return prop.id == X_PROPERTY_GAMER_PUID;
});

return PUID;
}
}
69 changes: 69 additions & 0 deletions src/domain/value-objects/Property.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { TinyTypeOf } from 'tiny-types';

export default class Property extends TinyTypeOf<string>() {
buffer: Buffer<ArrayBuffer>;
data: Buffer<ArrayBuffer>;

id_hex: string = '';
id: number = 0;
size: number = 0;
type: number = 0;

public constructor(base64: string) {
super(base64);

this.buffer = Buffer.from(base64, 'base64');

// Check if base64 is valid
if (this.buffer.toString('base64') !== base64) {
throw new Error('Invalid base64');
}

this.id = this.buffer.readInt32LE(0);
this.type = (this.buffer.readInt32BE(0) & 0xff) >> 4;
this.size = this.buffer.readInt32LE(4);

const offset: number = 8;
this.data = this.buffer.subarray(offset, offset + this.size);
this.id_hex = this.id.toString(16);
}

getUTF16() {
if (this.type != 4) {
return '';
}

const decoder = new TextDecoder('utf-16be');
const decoded_unicode: string = decoder.decode(this.data);

return decoded_unicode;
}

getData() {
return this.data;
}

getType() {
return this.type;
}

getID() {
return this.id;
}

getIDString() {
return this.id_hex;
}

getSize() {
return this.size;
}

toString(): string {
return this.value;
}

toStringPretty() {
return `ID: ${this.getIDString()} Type: ${this.getType()} Size: ${this.getSize()}`;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ import SessionFlags from 'src/domain/value-objects/SessionFlags';
import MacAddress from 'src/domain/value-objects/MacAddress';
import SessionId from 'src/domain/value-objects/SessionId';
import Xuid from 'src/domain/value-objects/Xuid';
import Property from 'src/domain/value-objects/Property';

@Injectable()
export default class SessionDomainMapper {
constructor(private readonly logger: ConsoleLogger) {}

public mapToDomainModel(session: SessionModel): Session {
const properties: Array<Property> = session.properties.map((prop) => {
return new Property(prop);
});

return new Session({
id: new SessionId(session.id),
titleId: new TitleId(session.titleId),
Expand All @@ -29,7 +34,7 @@ export default class SessionDomainMapper {
players: session.players,
deleted: session.deleted,
context: session.context,
properties: session.properties,
properties: properties,
migration: session.migration
? new SessionId(session.migration)
: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { Session as SessionModel } from '../models/SessionSchema';
@Injectable()
export default class SessionPersistanceMapper {
public mapToDataModel(session: Session, updatedAt: Date): SessionModel {
const properties: Array<string> = session.properties.map((prop) => {
return prop.toString();
});

return {
id: session.id.value,
titleId: session.titleId.toString(),
Expand All @@ -22,7 +26,7 @@ export default class SessionPersistanceMapper {
players: session.players,
deleted: session.deleted,
context: session.context,
properties: session.properties,
properties: properties,
migration: session.migration ? session.migration.value : undefined,
updatedAt,
};
Expand Down
2 changes: 1 addition & 1 deletion src/infrastructure/persistance/models/SessionSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class Session {
@Prop({ required: true })
context: Map<string, number>;
@Prop({ required: true })
properties: Map<string, number>;
properties: Array<string>;
@Prop({ required: false })
migration: string;

Expand Down
27 changes: 21 additions & 6 deletions src/infrastructure/presentation/controllers/session.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import { RealIP } from 'nestjs-real-ip';
import { ProcessClientAddressCommand } from 'src/application/commands/ProcessClientAddressCommand';
import Session from 'src/domain/aggregates/Session';
import { UpdatePlayerCommand } from 'src/application/commands/UpdatePlayerCommand';
import Property from 'src/domain/value-objects/Property';

@ApiTags('Sessions')
@Controller('/title/:titleId/sessions')
Expand Down Expand Up @@ -575,33 +576,47 @@ export class SessionController {

@Post('/:sessionId/properties')
@ApiParam({ name: 'titleId', example: '4D5307E6' })
@ApiParam({ name: 'sessionId', example: 'B36B3FE8467CFAC7' })
@ApiParam({ name: 'sessionId', example: 'AE00000000000000' })
async sessionPropertySet(
@Param('titleId') titleId: string,
@Param('sessionId') sessionId: string,
@Body() request: GetSessionPropertyRequest,
) {
const session = await this.commandBus.execute(
const properties: Array<Property> = request.properties.map(
(base64: string) => {
return new Property(base64);
},
);

const session: Session = await this.commandBus.execute(
new AddSessionPropertyCommand(
new TitleId(titleId),
new SessionId(sessionId),
request.properties,
properties,
),
);

this.logger.verbose(
`Host Gamer Name: ${session.propertyHostGamerName.getUTF16()}`,
);

this.logger.verbose(
`Host PUID: ${session.propertyPUID.getData().readBigInt64BE().toString(16).padStart(16, '0').toUpperCase()}`,
);

if (!session) {
throw new NotFoundException(`Session ${sessionId} was not found.`);
}
}

@Get('/:sessionId/properties')
@ApiParam({ name: 'titleId', example: '4D5307E6' })
@ApiParam({ name: 'sessionId', example: 'B36B3FE8467CFAC7' })
@ApiParam({ name: 'sessionId', example: 'AE00000000000000' })
async sessionPropertyGet(
@Param('titleId') titleId: string,
@Param('sessionId') sessionId: string,
): Promise<SessionPropertyResponse> {
const session = await this.queryBus.execute(
const session: Session = await this.queryBus.execute(
new GetSessionQuery(new TitleId(titleId), new SessionId(sessionId)),
);

Expand All @@ -610,7 +625,7 @@ export class SessionController {
}

return {
properties: session.properties,
properties: session.propertiesStringArray,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import { ApiProperty } from '@nestjs/swagger';

export class GetSessionPropertyRequest {
@ApiProperty()
properties: Map<number, { propertyId: number; value: number }>;
properties: Array<string>;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export interface SessionPropertyResponse {
properties: Map<number, number>;
properties: Array<string>;
}

0 comments on commit b5a8c1c

Please sign in to comment.