MBHaxe/src/net/NetCommands.hx
2024-05-01 14:23:33 +05:30

267 lines
8 KiB
Haxe

package net;
import net.ClientConnection.NetPlatform;
import gui.EndGameGui;
import modes.HuntMode;
import net.ClientConnection.GameplayState;
import net.Net.NetPacketType;
import gui.MultiplayerLevelSelectGui;
import src.MarbleGame;
import gui.MultiplayerLoadingGui;
import src.MissionList;
import src.Console;
@:build(net.RPCMacro.build())
class NetCommands {
@:rpc(server) public static function setLobbyLevelIndex(i:Int) {
if (MultiplayerLevelSelectGui.setLevelFn == null) {
MultiplayerLevelSelectGui.currentSelectionStatic = i;
} else {
MultiplayerLevelSelectGui.setLevelFn(i);
}
}
@:rpc(server) public static function playLevel(levelIndex:Int) {
MultiplayerLevelSelectGui.playSelectedLevel(levelIndex);
if (Net.isHost) {
Net.serverInfo.state = "WAITING";
MasterServerClient.instance.sendServerInfo(Net.serverInfo); // notify the server of the wait state
}
}
@:rpc(server) public static function playLevelMidJoin(index:Int) {
if (Net.isClient) {
var difficultyMissions = MissionList.missionList['ultra']["multiplayer"];
var curMission = difficultyMissions[index];
MarbleGame.instance.playMission(curMission, true);
}
}
@:rpc(server) public static function enterLobby() {
if (Net.isClient) {
MarbleGame.canvas.setContent(new MultiplayerLevelSelectGui(false));
}
}
@:rpc(server) public static function setNetworkRNG(rng:Float) {
Net.networkRNG = rng;
if (MarbleGame.instance.world != null) {
var gameMode = MarbleGame.instance.world.gameMode;
if (gameMode is modes.HuntMode) {
var hunt:modes.HuntMode = cast gameMode;
@:privateAccess hunt.rng.setSeed(cast rng);
@:privateAccess hunt.rng2.setSeed(cast rng);
}
}
}
@:rpc(client) public static function toggleReadiness(clientId:Int) {
if (Net.isHost) {
if (clientId == 0)
Net.lobbyHostReady = !Net.lobbyHostReady;
else
Net.clientIdMap[clientId].toggleLobbyReady();
var allReady = true;
for (id => client in Net.clientIdMap) {
if (!client.lobbyReady) {
allReady = false;
break;
}
}
if (MarbleGame.canvas.content is MultiplayerLevelSelectGui) {
cast(MarbleGame.canvas.content, MultiplayerLevelSelectGui).updateLobbyNames();
}
var b = Net.sendPlayerInfosBytes();
for (cc in Net.clients) {
cc.sendBytes(b);
}
if (allReady && Net.lobbyHostReady) {
NetCommands.playLevel(MultiplayerLevelSelectGui.currentSelectionStatic);
}
}
}
@:rpc(client) public static function clientIsReady(clientId:Int) {
if (Net.isHost) {
if (Net.serverInfo.state == "WAITING" && MarbleGame.instance.world != null) {
Net.clientIdMap[clientId].ready();
var allReady = true;
for (id => client in Net.clientIdMap) {
if (client.state != GameplayState.GAME) {
allReady = false;
break;
}
}
if (allReady) {
if (MarbleGame.instance.world != null) {
MarbleGame.instance.world.allClientsReady();
}
}
if (Net.isHost) {
Net.serverInfo.state = "PLAYING";
MasterServerClient.instance.sendServerInfo(Net.serverInfo); // notify the server of the playing state
}
} else {
// Mid game join
Console.log("Mid game join for client " + clientId);
// Send em our present world state
var packets = MarbleGame.instance.world.getWorldStateForClientJoin();
var c = Net.clientIdMap[clientId];
for (packet in packets) {
c.sendBytes(packet);
}
Net.clientIdMap[clientId].ready();
// Send the start ticks
NetCommands.setStartTicksMidJoinClient(c, MarbleGame.instance.world.serverStartTicks, MarbleGame.instance.world.timeState.ticks);
}
}
}
@:rpc(server) public static function addMidGameJoinMarble(cc:Int) {
if (Net.isClient) {
if (MarbleGame.instance.world != null) {
MarbleGame.instance.world.addJoiningClientGhost(Net.clientIdMap[cc], () -> {});
}
}
}
@:rpc(server) public static function setStartTicks(ticks:Int) {
if (MarbleGame.instance.world != null) {
MarbleGame.instance.world.serverStartTicks = ticks + 1; // Extra tick so we don't get 0
MarbleGame.instance.world.startTime = MarbleGame.instance.world.timeState.timeSinceLoad + 3.5 + 0.032; // 1 extra tick
}
}
@:rpc(server) public static function setStartTicksMidJoin(startTicks:Int, currentTicks:Int) {
if (MarbleGame.instance.world != null) {
MarbleGame.instance.world.serverStartTicks = startTicks + 1; // Extra tick so we don't get 0
MarbleGame.instance.world.startTime = MarbleGame.instance.world.timeState.timeSinceLoad + 0.032; // 1 extra tick
MarbleGame.instance.world.timeState.ticks = currentTicks;
}
}
@:rpc(server) public static function timerRanOut() {
if (Net.isClient && MarbleGame.instance.world != null) {
var huntMode:HuntMode = cast MarbleGame.instance.world.gameMode;
huntMode.onTimeExpire();
}
if (Net.isHost) {
Net.serverInfo.state = "WAITING";
MasterServerClient.instance.sendServerInfo(Net.serverInfo); // notify the server of the playing state
}
}
@:rpc(server) public static function clientDisconnected(clientId:Int) {
var conn = Net.clientIdMap.get(clientId);
if (MarbleGame.instance.world != null) {
MarbleGame.instance.world.removePlayer(conn);
var allReady = true;
for (id => client in Net.clientIdMap) {
if (client.state != GameplayState.GAME) {
allReady = false;
break;
}
}
if (allReady && MarbleGame.instance.world.serverStartTicks == 0) {
MarbleGame.instance.world.allClientsReady();
}
}
Net.clientIdMap.remove(clientId);
if (MarbleGame.canvas.content is MultiplayerLevelSelectGui) {
cast(MarbleGame.canvas.content, MultiplayerLevelSelectGui).updateLobbyNames();
}
}
@:rpc(server) public static function clientJoin(clientId:Int) {}
@:rpc(client) public static function clientLeave(clientId:Int) {
if (Net.isHost) {
@:privateAccess Net.onClientLeave(cast Net.clientIdMap[clientId]);
}
}
@:rpc(server) public static function serverClosed() {
if (Net.isClient) {
if (MarbleGame.instance.world != null) {
MarbleGame.instance.quitMission();
}
var loadGui = new MultiplayerLoadingGui("Server closed");
MarbleGame.canvas.setContent(loadGui);
loadGui.setErrorStatus("Server closed");
}
}
@:rpc(client) public static function setPlayerData(clientId:Int, name:String, marble:Int) {
if (Net.isHost) {
Net.clientIdMap[clientId].setName(name);
Net.clientIdMap[clientId].setMarbleId(marble);
if (MarbleGame.canvas.content is MultiplayerLevelSelectGui) {
cast(MarbleGame.canvas.content, MultiplayerLevelSelectGui).updateLobbyNames();
}
}
}
@:rpc(client) public static function transmitPlatform(clientId:Int, platform:Int) {
if (Net.isHost) {
Net.clientIdMap[clientId].platform = platform;
if (MarbleGame.canvas.content is MultiplayerLevelSelectGui) {
cast(MarbleGame.canvas.content, MultiplayerLevelSelectGui).updateLobbyNames();
}
}
}
@:rpc(server) public static function endGame() {
for (c => v in Net.clientIdMap) {
v.state = LOBBY;
v.lobbyReady = false;
}
if (Net.isClient) {
if (MarbleGame.instance.world != null) {
MarbleGame.instance.quitMission();
}
}
if (Net.isHost) {
Net.lobbyHostReady = false;
if (Net.isHost) {
Net.serverInfo.state = "LOBBY";
MasterServerClient.instance.sendServerInfo(Net.serverInfo); // notify the server of the playing state
}
}
}
@:rpc(server) public static function restartGame() {
var world = MarbleGame.instance.world;
if (Net.isHost) {
world.startTime = 1e8;
haxe.Timer.delay(() -> world.allClientsReady(), 1500);
}
if (Net.isClient) {
var gui = MarbleGame.canvas.children[MarbleGame.canvas.children.length - 1];
if (gui is EndGameGui) {
var egg = cast(gui, EndGameGui);
egg.retryFunc(null);
world.restartMultiplayerState();
}
}
world.multiplayerStarted = false;
}
@:rpc(server) public static function ping(sendTime:Float) {
if (Net.isClient) {
pingBack(Console.time() - sendTime);
}
}
@:rpc(client) public static function pingBack(ping:Float) {
// Do nothing???
}
@:rpc(client) public static function requestPing() {
if (Net.isHost) {
ping(Console.time());
}
}
}