Skip to content

Commit

Permalink
start multiplayer stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
brxxn committed Dec 18, 2024
1 parent eb4b3b5 commit 59c7e8b
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 0 deletions.
4 changes: 4 additions & 0 deletions protocol/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Protocol

This directory stores all protocol buffers used by the various different projects here. We maintain them in this
directory so that we do not have to maintain separate files in each project.
73 changes: 73 additions & 0 deletions protocol/playserver.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
syntax = "proto3";

enum ClientMessageType {
PING = 0;
CONNECT = 1;
SEND = 2;
BULKSEND = 3;
}

enum ServerMessageType {
PONG = 0;
CONNACK = 1;
RECV = 2;
BULKRECV = 3;
}

enum DsPacketType {
GENERIC = 0;
CMD = 1;
REPLY = 2;
ACK = 3;
}

enum ConnAckFailureReason {
SERVER_FULL = 0;
INCORRECT_PASSWORD = 1;
CLIENT_VERSION_INVALID = 2;
SERVER_VERSION_INVALID = 3;
INVALID_NAME = 4;
ALREADY_CONNECTED = 5;
REMOTE_ERROR = 6;
}

message DsPacket {
DsPacketType packet_type = 1;
bytes data = 2;
uint64 timestamp = 3;
optional uint32 aid = 4;
}

message ConnectPacket {
uint32 client_version = 1;
string name = 2;
optional string password = 3;
}

message ConnAckPacket {
bool success = 1;
optional ConnAckFailureReason fail_reason = 2;
optional string remote_error = 3;
}

message BulkPackets {
repeated DsPacket packets = 1;
}

message ClientMessage {
ClientMessageType msg_type = 1;
oneof msg_content {
ConnectPacket connect_packet = 2;
DsPacket ds_packet = 3;
BulkPackets bulk_packets = 4;
}
}

message ServerMessage {
ServerMessageType msg_type = 1;
oneof msg_content {
ConnAckPacket connack_packet = 2;
DsPacket ds_packet = 3;
BulkPackets bulk_packets = 4;
}
}
29 changes: 29 additions & 0 deletions webmelon-sdk/webmelon.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,29 @@ interface WebMelonConstants {
FIRMWARE_LANGUAGES: WebMelonFirmwareLanguage[];
};

interface WebMelonRecvPacketResponse {
data: UInt8Array;
timestamp: number;
};

interface WebMelonRecvReplyPacketResponse {
data: UInt8Array;
timestamp: number;
aid: number;
};

interface WebMelonMPController {
initialize: () => void;
end: () => void;
sendPacket: (data: UInt8Array, timestamp: number) => void;
recvPacket: () => WebMelonRecvPacketResponse?;
sendCmd: (data: UInt8Array, timestamp: number) => void;
sendReply:(data: UInt8Array, timestamp: number, aid: number) => void;
sendAck: (data: Uint8Array, timestamp: number) => void;
recvHostPacket: () => WebMelonRecvPacketResponse?;
recvReplies: (timestamp: number, aidmask: number) => WebMelonRecvReplyPacketResponse[];
};

interface WebMelonCart {
createCart: () => void;
loadFileIntoCart: (filename: string) => boolean;
Expand Down Expand Up @@ -92,13 +115,19 @@ interface WebMelonInput {
setRumbleEnabled: (enabled: boolean) => void;
};

interface WebMelonMultiplayer {
setInterface: (interface: WebMelonMPController) => void;
removeInterface: () => void;
};

interface WebMelonInterface {
cart: WebMelonCart;
constants: WebMelonConstants;
storage: WebMelonStorage;
emulator: WebMelonEmulator;
firmware: WebMelonFirmware;
input: WebMelonInput;
multiplayer: WebMelonMultiplayer;
};

interface Window {
Expand Down
63 changes: 63 additions & 0 deletions webmelon-sdk/webmelon.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,39 @@
vfsInitialized: []
};

// This class is used as the initial "offline" multiplayer inteface that just returns nothing
class OfflineMPInterface {
constructor() {}
initialize() {
console.log('Offline MP initialize called');
}
end() {
console.log('Offline MP end called');
}
sendPacket(data, timestamp) {
console.debug([data, timestamp]);
}
recvPacket() {
return undefined;
}
sendCmd(data, timestamp) {
console.debug([data, timestamp]);
}
sendReply(data, timestamp, aid) {
console.debug([data, timestamp, aid]);
}
sendAck(data, timestamp) {
console.debug([data, timestamp]);
}
recvHostPacket() {
return undefined;
}
recvReplies() {
return [];
}
};
const defaultMpInterface = new OfflineMPInterface();

let WebMelon = {
// Things in here should only be used by the SDK itself. This does not need to (and should not be)
// included in TypeScript bindings. The reason we do not keep it as a local variable here in the
Expand Down Expand Up @@ -194,6 +227,7 @@
gamepadBinds: DefaultGamepadBindings,
gamepadRumbleIntensity: 0.5
},
mpInterface: defaultMpInterface,
subscribers: DefaultSubscribers,
storage: {
initialized: false,
Expand Down Expand Up @@ -709,6 +743,35 @@
});
}
}
},
multiplayer: {
_sendPacket: (dataPtr, length, timestamp) => {
const data = new Uint8Array(Module.HEAPU8.buffer, dataPtr, length);
WebMelon._internal.mpInterface.sendPacket(data, timestamp);
},
_sendCmd: (dataPtr, length, timestamp) => {
const data = new Uint8Array(Module.HEAPU8.buffer, dataPtr, length);
WebMelon._internal.mpInterface.sendCmd(data, timestamp);
},
_sendReply: (dataPtr, length, timestamp, aid) => {
const data = new Uint8Array(Module.HEAPU8.buffer, dataPtr, length);
WebMelon._internal.mpInterface.sendReply(data, timestamp, aid);
},
_sendAck: (dataPtr, length, timestamp) => {
const data = new Uint8Array(Module.HEAPU8.buffer, dataPtr, length);
WebMelon._internal.mpInterface.sendAck(data, timestamp);
},
_recvPacket: (dataPtr, timestampPtr) => {
const receivedPacket = WebMelon._internal.mpInterface.recvPacket();
if (!receivedPacket) return;

},
setInterface: (mpInterface) => {
WebMelon._internal.mpInterface = mpInterface;
},
removeInterface: () => {
WebMelon.multiplayer.setInterface(defaultMpInterface);
}
}
};

Expand Down

0 comments on commit 59c7e8b

Please sign in to comment.