mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
add dummy connections
This commit is contained in:
parent
d833ac8a2b
commit
ef92860d89
11 changed files with 210 additions and 60 deletions
|
|
@ -1,5 +1,6 @@
|
|||
package src;
|
||||
|
||||
import net.Net;
|
||||
#if !js
|
||||
import sys.FileSystem;
|
||||
#end
|
||||
|
|
@ -187,6 +188,8 @@ class Console {
|
|||
} else if (cmdType == 'rollback') {
|
||||
var t = Std.parseFloat(cmdSplit[1]);
|
||||
MarbleGame.instance.world.rollback(t);
|
||||
} else if (cmdType == 'addDummy') {
|
||||
Net.addDummyConnection();
|
||||
} else {
|
||||
error("Unknown command");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package src;
|
||||
|
||||
import net.ClientConnection;
|
||||
import net.ClientConnection.GameConnection;
|
||||
import net.NetPacket.MarbleUpdatePacket;
|
||||
import net.MoveManager;
|
||||
import net.MoveManager.NetMove;
|
||||
|
|
@ -292,7 +294,7 @@ class Marble extends GameObject {
|
|||
|
||||
public var cubemapRenderer:CubemapRenderer;
|
||||
|
||||
var connection:net.Net.ClientConnection;
|
||||
var connection:GameConnection;
|
||||
var moveMotionDir:Vector;
|
||||
var lastMove:Move;
|
||||
var isNetUpdate:Bool = false;
|
||||
|
|
@ -332,7 +334,7 @@ class Marble extends GameObject {
|
|||
this.helicopterSound.pause = true;
|
||||
}
|
||||
|
||||
public function init(level:MarbleWorld, connection:ClientConnection, onFinish:Void->Void) {
|
||||
public function init(level:MarbleWorld, connection:GameConnection, onFinish:Void->Void) {
|
||||
this.level = level;
|
||||
this.connection = connection;
|
||||
if (this.level != null)
|
||||
|
|
@ -1060,6 +1062,7 @@ class Marble extends GameObject {
|
|||
searchbox.addSpherePos(position.x + velocity.x * deltaT, position.y + velocity.y * deltaT, position.z + velocity.z * deltaT, _radius);
|
||||
|
||||
var foundObjs = this.collisionWorld.boundingSearch(searchbox);
|
||||
foundObjs.push(this.collisionWorld.staticWorld);
|
||||
|
||||
var finalT = deltaT;
|
||||
var found = false;
|
||||
|
|
@ -1102,7 +1105,7 @@ class Marble extends GameObject {
|
|||
// var iterationFound = false;
|
||||
for (obj in foundObjs) {
|
||||
// Its an MP so bruh
|
||||
if (!obj.go.isCollideable)
|
||||
if (obj.go != null && !obj.go.isCollideable)
|
||||
continue;
|
||||
|
||||
var invMatrix = @:privateAccess obj.invTransform;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ import net.NetPacket.MarbleMovePacket;
|
|||
import net.MoveManager;
|
||||
import net.NetCommands;
|
||||
import net.Net;
|
||||
import net.Net.ClientConnection;
|
||||
import net.ClientConnection;
|
||||
import net.ClientConnection.GameConnection;
|
||||
import rewind.InputRecorder;
|
||||
import gui.AchievementsGui;
|
||||
import src.Radar;
|
||||
|
|
@ -203,7 +204,7 @@ class MarbleWorld extends Scheduler {
|
|||
var tickAccumulator:Float = 0.0;
|
||||
var maxPredictionTicks:Int = 16;
|
||||
|
||||
var clientMarbles:Map<ClientConnection, Marble> = [];
|
||||
var clientMarbles:Map<GameConnection, Marble> = [];
|
||||
|
||||
public var lastMoves:MarbleUpdateQueue;
|
||||
|
||||
|
|
@ -307,7 +308,7 @@ class MarbleWorld extends Scheduler {
|
|||
this.gameMode.missionScan(this.mission);
|
||||
this.resourceLoadFuncs.push(fwd -> this.initScene(fwd));
|
||||
if (this.isMultiplayer) {
|
||||
for (client in Net.clients) {
|
||||
for (client in Net.clientIdMap) {
|
||||
this.resourceLoadFuncs.push(fwd -> this.initMarble(client, fwd)); // Others
|
||||
}
|
||||
}
|
||||
|
|
@ -322,6 +323,7 @@ class MarbleWorld extends Scheduler {
|
|||
|
||||
public function postInit() {
|
||||
// Add the sky at the last so that cubemap reflections work
|
||||
this.collisionWorld.finalizeStaticGeometry();
|
||||
this.playGui.init(this.scene2d, this.mission.game.toLowerCase());
|
||||
this.scene.addChild(this.sky);
|
||||
this._ready = true;
|
||||
|
|
@ -415,7 +417,7 @@ class MarbleWorld extends Scheduler {
|
|||
worker.run();
|
||||
}
|
||||
|
||||
public function initMarble(client:ClientConnection, onFinish:Void->Void) {
|
||||
public function initMarble(client:GameConnection, onFinish:Void->Void) {
|
||||
Console.log("Initializing marble");
|
||||
var worker = new ResourceLoaderWorker(onFinish);
|
||||
var marblefiles = [
|
||||
|
|
@ -767,8 +769,11 @@ class MarbleWorld extends Scheduler {
|
|||
var tmat = Matrix.T(interiorPosition.x, interiorPosition.y, interiorPosition.z);
|
||||
mat.multiply(mat, tmat);
|
||||
|
||||
if (hasCollision)
|
||||
this.collisionWorld.addStaticInterior(interior.collider, mat);
|
||||
|
||||
interior.isCollideable = false;
|
||||
interior.setTransform(mat);
|
||||
interior.isCollideable = hasCollision;
|
||||
onFinish();
|
||||
});
|
||||
|
||||
|
|
@ -886,7 +891,7 @@ class MarbleWorld extends Scheduler {
|
|||
public function addInterior(obj:InteriorObject, onFinish:Void->Void) {
|
||||
this.interiors.push(obj);
|
||||
obj.init(cast this, () -> {
|
||||
this.collisionWorld.addEntity(obj.collider);
|
||||
// this.collisionWorld.addEntity(obj.collider);
|
||||
if (obj.useInstancing)
|
||||
this.instanceManager.addObject(obj);
|
||||
else
|
||||
|
|
@ -970,7 +975,7 @@ class MarbleWorld extends Scheduler {
|
|||
});
|
||||
}
|
||||
|
||||
public function addMarble(marble:Marble, client:ClientConnection, onFinish:Void->Void) {
|
||||
public function addMarble(marble:Marble, client:GameConnection, onFinish:Void->Void) {
|
||||
marble.level = cast this;
|
||||
if (marble.controllable) {
|
||||
marble.init(cast this, client, () -> {
|
||||
|
|
@ -1379,7 +1384,7 @@ class MarbleWorld extends Scheduler {
|
|||
// return (a.c == client.id) ? 1 : (b.c == client.id) ? -1 : 0;
|
||||
// });
|
||||
for (packet in packets) {
|
||||
client.datachannel.sendBytes(packet);
|
||||
client.sendBytes(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
|
|||
|
||||
public var userData:Int;
|
||||
public var fastTransform:Bool = false;
|
||||
public var isWorldStatic:Bool = false;
|
||||
|
||||
var _transformKey:Int = 0;
|
||||
|
||||
|
|
@ -187,6 +188,11 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
|
|||
var tform = transform.clone();
|
||||
// tform.setPosition(tform.getPosition().add(this.velocity.multiply(timeState.dt)));
|
||||
|
||||
if (isWorldStatic) {
|
||||
tform.load(Matrix.I());
|
||||
invtform.load(Matrix.I());
|
||||
}
|
||||
|
||||
var contacts = [];
|
||||
|
||||
for (obj in surfaces) {
|
||||
|
|
@ -246,7 +252,8 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
|
|||
cinfo.force = surface.force;
|
||||
cinfo.friction = surface.friction;
|
||||
contacts.push(cinfo);
|
||||
this.go.onMarbleContact(collisionEntity.marble, timeState, cinfo);
|
||||
if (this.go != null)
|
||||
this.go.onMarbleContact(collisionEntity.marble, timeState, cinfo);
|
||||
// surfaceBestContact = cinfo;
|
||||
// }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,6 +219,42 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
|
|||
new Vector(_transformedNormals[p1 * 3], _transformedNormals[p1 * 3 + 1], _transformedNormals[p1 * 3 + 2]));
|
||||
}
|
||||
|
||||
public inline function getTriangle(idx:Int) {
|
||||
var p1 = indices[idx];
|
||||
var p2 = indices[idx + 1];
|
||||
var p3 = indices[idx + 2];
|
||||
|
||||
return new TransformedCollisionTriangle(getPoint(p1), getPoint(p2), getPoint(p3), getNormal(p1));
|
||||
}
|
||||
|
||||
public function getTransformed(m:Matrix, invtform:Matrix) {
|
||||
var tformed = new CollisionSurface();
|
||||
tformed.points = this.points.copy();
|
||||
tformed.normals = this.normals.copy();
|
||||
tformed.indices = this.indices.copy();
|
||||
tformed.friction = this.friction;
|
||||
tformed.force = this.force;
|
||||
tformed.restitution = this.restitution;
|
||||
tformed.transformKeys = this.transformKeys.copy();
|
||||
|
||||
for (i in 0...Std.int(points.length / 3)) {
|
||||
var v = getPoint(i);
|
||||
var v2 = v.transformed(m);
|
||||
tformed.points[i * 3] = v2.x;
|
||||
tformed.points[i * 3 + 1] = v2.y;
|
||||
tformed.points[i * 3 + 2] = v2.z;
|
||||
|
||||
var n = getNormal(i);
|
||||
var n2 = n.transformed3x3(invtform).normalized();
|
||||
tformed.normals[i * 3] = n2.x;
|
||||
tformed.normals[i * 3 + 1] = n2.y;
|
||||
tformed.normals[i * 3 + 2] = n2.z;
|
||||
}
|
||||
tformed.generateBoundingBox();
|
||||
|
||||
return tformed;
|
||||
}
|
||||
|
||||
public function dispose() {
|
||||
points = null;
|
||||
normals = null;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package collision;
|
||||
|
||||
import h3d.Matrix;
|
||||
import src.MarbleGame;
|
||||
import src.TimeState;
|
||||
import h3d.col.Bounds;
|
||||
|
|
@ -8,6 +9,7 @@ import h3d.Vector;
|
|||
import octree.Octree;
|
||||
|
||||
class CollisionWorld {
|
||||
public var staticWorld:CollisionEntity;
|
||||
public var octree:Octree;
|
||||
public var entities:Array<CollisionEntity> = [];
|
||||
public var dynamicEntities:Array<CollisionEntity> = [];
|
||||
|
|
@ -20,6 +22,7 @@ class CollisionWorld {
|
|||
public function new() {
|
||||
this.octree = new Octree();
|
||||
this.dynamicOctree = new Octree();
|
||||
this.staticWorld = new CollisionEntity(null);
|
||||
}
|
||||
|
||||
public function sphereIntersection(spherecollision:SphereCollisionEntity, timeState:TimeState) {
|
||||
|
|
@ -50,6 +53,8 @@ class CollisionWorld {
|
|||
}
|
||||
}
|
||||
|
||||
contacts = contacts.concat(this.staticWorld.sphereIntersection(spherecollision, timeState));
|
||||
|
||||
var dynSearch = dynamicOctree.boundingSearch(box).map(x -> cast(x, CollisionEntity));
|
||||
for (obj in dynSearch) {
|
||||
if (obj != spherecollision) {
|
||||
|
|
@ -116,6 +121,7 @@ class CollisionWorld {
|
|||
for (obj in objs) {
|
||||
results = results.concat(obj.rayCast(rayStart, rayDirection));
|
||||
}
|
||||
results = results.concat(this.staticWorld.rayCast(rayStart, rayDirection));
|
||||
return results;
|
||||
}
|
||||
|
||||
|
|
@ -153,6 +159,17 @@ class CollisionWorld {
|
|||
}
|
||||
}
|
||||
|
||||
public function addStaticInterior(entity:CollisionEntity, transform:Matrix) {
|
||||
var invTform = transform.getInverse();
|
||||
for (surf in entity.surfaces) {
|
||||
staticWorld.addSurface(surf.getTransformed(transform, invTform));
|
||||
}
|
||||
}
|
||||
|
||||
public function finalizeStaticGeometry() {
|
||||
this.staticWorld.finalize();
|
||||
}
|
||||
|
||||
public function dispose() {
|
||||
for (e in entities) {
|
||||
e.dispose();
|
||||
|
|
@ -165,5 +182,7 @@ class CollisionWorld {
|
|||
dynamicEntities = null;
|
||||
dynamicOctree = null;
|
||||
dynamicEntitySet = null;
|
||||
staticWorld.dispose();
|
||||
staticWorld = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ class HuntState implements RewindableState {
|
|||
class HuntMode extends NullMode {
|
||||
var gemSpawnPoints:Array<GemSpawnSphere> = [];
|
||||
var playerSpawnPoints:Array<MissionElementSpawnSphere> = [];
|
||||
var spawnPointTaken = [];
|
||||
|
||||
var gemOctree:Octree;
|
||||
var gemGroupRadius:Float;
|
||||
|
|
@ -170,8 +171,10 @@ class HuntMode extends NullMode {
|
|||
if ([MissionElementType.SpawnSphere].contains(element._type)) {
|
||||
var spawnSphere:MissionElementSpawnSphere = cast element;
|
||||
var dbname = spawnSphere.datablock.toLowerCase();
|
||||
if (dbname == "spawnspheremarker")
|
||||
if (dbname == "spawnspheremarker") {
|
||||
playerSpawnPoints.push(spawnSphere);
|
||||
spawnPointTaken.push(false);
|
||||
}
|
||||
if (dbname == "gemspawnspheremarker")
|
||||
gemSpawnPoints.push(new GemSpawnSphere(spawnSphere));
|
||||
} else if (element._type == MissionElementType.SimGroup) {
|
||||
|
|
@ -183,7 +186,12 @@ class HuntMode extends NullMode {
|
|||
};
|
||||
|
||||
override function getSpawnTransform() {
|
||||
var randomSpawn = playerSpawnPoints[Math.floor(rng2.randRange(0, playerSpawnPoints.length - 1))];
|
||||
var idx = Math.floor(rng2.randRange(0, playerSpawnPoints.length - 1));
|
||||
while (spawnPointTaken[idx]) {
|
||||
idx = Math.floor(rng2.randRange(0, playerSpawnPoints.length - 1));
|
||||
}
|
||||
spawnPointTaken[idx] = true;
|
||||
var randomSpawn = playerSpawnPoints[idx];
|
||||
var spawnPos = MisParser.parseVector3(randomSpawn.position);
|
||||
spawnPos.x *= -1;
|
||||
var spawnRot = MisParser.parseRotation(randomSpawn.rotation);
|
||||
|
|
|
|||
59
src/net/ClientConnection.hx
Normal file
59
src/net/ClientConnection.hx
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package net;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import datachannel.RTCPeerConnection;
|
||||
import datachannel.RTCDataChannel;
|
||||
import net.MoveManager;
|
||||
|
||||
enum abstract GameplayState(Int) from Int to Int {
|
||||
var UNKNOWN;
|
||||
var LOBBY;
|
||||
var GAME;
|
||||
}
|
||||
|
||||
@:publicFields
|
||||
class ClientConnection extends GameConnection {
|
||||
var socket:RTCPeerConnection;
|
||||
var datachannel:RTCDataChannel;
|
||||
var rtt:Float;
|
||||
var pingSendTime:Float;
|
||||
var _rttRecords:Array<Float> = [];
|
||||
|
||||
public function new(id:Int, socket:RTCPeerConnection, datachannel:RTCDataChannel) {
|
||||
super(id);
|
||||
this.socket = socket;
|
||||
this.datachannel = datachannel;
|
||||
this.state = GameplayState.LOBBY;
|
||||
this.rtt = 0;
|
||||
}
|
||||
|
||||
override function sendBytes(b:Bytes) {
|
||||
datachannel.sendBytes(b);
|
||||
}
|
||||
}
|
||||
|
||||
@:publicFields
|
||||
class DummyConnection extends GameConnection {
|
||||
public function new(id:Int) {
|
||||
super(id);
|
||||
this.state = GameplayState.GAME;
|
||||
}
|
||||
}
|
||||
|
||||
@:publicFields
|
||||
abstract class GameConnection {
|
||||
var id:Int;
|
||||
var state:GameplayState;
|
||||
var moveManager:MoveManager;
|
||||
|
||||
public function new(id:Int) {
|
||||
this.id = id;
|
||||
this.moveManager = new MoveManager(this);
|
||||
}
|
||||
|
||||
public function ready() {
|
||||
state = GameplayState.GAME;
|
||||
}
|
||||
|
||||
public function sendBytes(b:haxe.io.Bytes) {}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ import shapes.PowerUp;
|
|||
import net.NetPacket.MarbleMovePacket;
|
||||
import src.TimeState;
|
||||
import src.Console;
|
||||
import net.Net.ClientConnection;
|
||||
import net.ClientConnection;
|
||||
import net.Net.NetPacketType;
|
||||
import src.MarbleWorld;
|
||||
import src.Marble.Move;
|
||||
|
|
@ -38,7 +38,7 @@ class NetMove {
|
|||
}
|
||||
|
||||
class MoveManager {
|
||||
var connection:ClientConnection;
|
||||
var connection:GameConnection;
|
||||
var queuedMoves:Array<NetMove>;
|
||||
var nextMoveId:Int;
|
||||
var lastMove:NetMove;
|
||||
|
|
@ -49,10 +49,12 @@ class MoveManager {
|
|||
|
||||
public var stall = false;
|
||||
|
||||
public function new(connection:ClientConnection) {
|
||||
public function new(connection:GameConnection) {
|
||||
queuedMoves = [];
|
||||
nextMoveId = 0;
|
||||
this.connection = connection;
|
||||
var mv = new Move();
|
||||
mv.d = new Vector(0, 0);
|
||||
}
|
||||
|
||||
public function recordMove(marble:Marble, motionDir:Vector, timeState:TimeState) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package net;
|
||||
|
||||
import net.ClientConnection;
|
||||
import net.NetPacket.MarbleUpdatePacket;
|
||||
import net.NetPacket.MarbleMovePacket;
|
||||
import haxe.Json;
|
||||
|
|
@ -11,12 +12,6 @@ import net.NetCommands;
|
|||
import src.MarbleGame;
|
||||
import hx.ws.Types.MessageType;
|
||||
|
||||
enum abstract GameplayState(Int) from Int to Int {
|
||||
var UNKNOWN;
|
||||
var LOBBY;
|
||||
var GAME;
|
||||
}
|
||||
|
||||
enum abstract NetPacketType(Int) from Int to Int {
|
||||
var NullPacket;
|
||||
var ClientIdAssign;
|
||||
|
|
@ -25,31 +20,7 @@ enum abstract NetPacketType(Int) from Int to Int {
|
|||
var PingBack;
|
||||
var MarbleUpdate;
|
||||
var MarbleMove;
|
||||
}
|
||||
|
||||
@:publicFields
|
||||
class ClientConnection {
|
||||
var id:Int;
|
||||
var socket:RTCPeerConnection;
|
||||
var datachannel:RTCDataChannel;
|
||||
var state:GameplayState;
|
||||
var moveManager:MoveManager;
|
||||
var rtt:Float;
|
||||
var pingSendTime:Float;
|
||||
var _rttRecords:Array<Float> = [];
|
||||
|
||||
public function new(id:Int, socket:RTCPeerConnection, datachannel:RTCDataChannel) {
|
||||
this.socket = socket;
|
||||
this.datachannel = datachannel;
|
||||
this.id = id;
|
||||
this.state = GameplayState.LOBBY;
|
||||
this.rtt = 0;
|
||||
this.moveManager = new MoveManager(this);
|
||||
}
|
||||
|
||||
public function ready() {
|
||||
state = GameplayState.GAME;
|
||||
}
|
||||
var PlayerInfo;
|
||||
}
|
||||
|
||||
class Net {
|
||||
|
|
@ -66,8 +37,8 @@ class Net {
|
|||
|
||||
public static var clientId:Int;
|
||||
public static var networkRNG:Float;
|
||||
public static var clients:Map<RTCPeerConnection, ClientConnection> = [];
|
||||
public static var clientIdMap:Map<Int, ClientConnection> = [];
|
||||
public static var clients:Map<RTCPeerConnection, GameConnection> = [];
|
||||
public static var clientIdMap:Map<Int, GameConnection> = [];
|
||||
public static var clientConnection:ClientConnection;
|
||||
|
||||
public static function hostServer() {
|
||||
|
|
@ -105,7 +76,7 @@ class Net {
|
|||
peer.onGatheringStateChange = (s) -> {
|
||||
if (s == RTC_GATHERING_COMPLETE) {
|
||||
var sdpObj = StringTools.trim(peer.localDescription);
|
||||
sdpObj = sdpObj + '\r\n' + candidates.join('\r\n');
|
||||
sdpObj = sdpObj + '\r\n' + candidates.join('\r\n') + '\r\n';
|
||||
masterWs.send(Json.stringify({
|
||||
type: "connect",
|
||||
sdpObj: {
|
||||
|
|
@ -120,6 +91,11 @@ class Net {
|
|||
}
|
||||
}
|
||||
|
||||
static function addGhost(id:Int) {
|
||||
var ghost = new DummyConnection(id);
|
||||
clientIdMap[id] = ghost;
|
||||
}
|
||||
|
||||
public static function joinServer(connectedCb:() -> Void) {
|
||||
masterWs = new WebSocket("ws://localhost:8080");
|
||||
masterWs.onopen = () -> {
|
||||
|
|
@ -134,7 +110,7 @@ class Net {
|
|||
if (s == RTC_GATHERING_COMPLETE) {
|
||||
Console.log("Local Description Set!");
|
||||
var sdpObj = StringTools.trim(client.localDescription);
|
||||
sdpObj = sdpObj + '\r\n' + candidates.join('\r\n');
|
||||
sdpObj = sdpObj + '\r\n' + candidates.join('\r\n') + '\r\n';
|
||||
masterWs.send(Json.stringify({
|
||||
type: "connect",
|
||||
sdpObj: {
|
||||
|
|
@ -160,7 +136,7 @@ class Net {
|
|||
Console.log("Successfully connected!");
|
||||
clients.set(client, new ClientConnection(0, client, clientDatachannel)); // host is always 0
|
||||
clientIdMap[0] = clients[client];
|
||||
clientConnection = clients[client];
|
||||
clientConnection = cast clients[client];
|
||||
onConnectedToServer();
|
||||
haxe.Timer.delay(() -> connectedCb(), 1500); // 1.5 second delay to do the RTT calculation
|
||||
}
|
||||
|
|
@ -190,7 +166,7 @@ class Net {
|
|||
var b = haxe.io.Bytes.alloc(2);
|
||||
b.set(0, Ping);
|
||||
b.set(1, 3); // Count
|
||||
clients[c].pingSendTime = Console.time();
|
||||
cast(clients[c], ClientConnection).pingSendTime = Console.time();
|
||||
dc.sendBytes(b);
|
||||
Console.log("Sending ping packet!");
|
||||
}
|
||||
|
|
@ -201,11 +177,23 @@ class Net {
|
|||
var b = haxe.io.Bytes.alloc(2);
|
||||
b.set(0, Ping);
|
||||
b.set(1, 3); // Count
|
||||
clients[client].pingSendTime = Console.time();
|
||||
cast(clients[client], ClientConnection).pingSendTime = Console.time();
|
||||
clientDatachannel.sendBytes(b);
|
||||
Console.log("Sending ping packet!");
|
||||
}
|
||||
|
||||
static function sendPlayerInfosBytes() {
|
||||
var b = new haxe.io.BytesOutput();
|
||||
b.writeByte(PlayerInfo);
|
||||
var cnt = 0;
|
||||
for (c in clientIdMap)
|
||||
cnt++;
|
||||
b.writeByte(cnt);
|
||||
for (c => v in clientIdMap)
|
||||
b.writeByte(c);
|
||||
return b.getBytes();
|
||||
}
|
||||
|
||||
static function onPacketReceived(c:RTCPeerConnection, dc:RTCDataChannel, input:haxe.io.BytesInput) {
|
||||
var packetType = input.readByte();
|
||||
switch (packetType) {
|
||||
|
|
@ -227,7 +215,7 @@ class Net {
|
|||
case PingBack:
|
||||
var pingLeft = input.readByte();
|
||||
Console.log("Got pingback packet!");
|
||||
var conn = clients[c];
|
||||
var conn:ClientConnection = cast clients[c];
|
||||
var now = Console.time();
|
||||
conn._rttRecords.push((now - conn.pingSendTime));
|
||||
if (pingLeft > 0) {
|
||||
|
|
@ -241,6 +229,10 @@ class Net {
|
|||
conn.rtt += r;
|
||||
conn.rtt /= conn._rttRecords.length;
|
||||
Console.log('Got RTT ${conn.rtt} for client ${conn.id}');
|
||||
if (Net.isHost) {
|
||||
var b = sendPlayerInfosBytes();
|
||||
conn.sendBytes(b);
|
||||
}
|
||||
}
|
||||
|
||||
case MarbleUpdate:
|
||||
|
|
@ -258,15 +250,25 @@ class Net {
|
|||
var cc = clientIdMap[movePacket.clientId];
|
||||
cc.moveManager.queueMove(movePacket.move);
|
||||
|
||||
case PlayerInfo:
|
||||
var count = input.readByte();
|
||||
for (i in 0...count) {
|
||||
var id = input.readByte();
|
||||
if (id != 0 && id != Net.clientId && !clientIdMap.exists(id)) {
|
||||
Console.log('Adding ghost connection ${id}');
|
||||
addGhost(id);
|
||||
}
|
||||
}
|
||||
|
||||
case _:
|
||||
trace("unknown command: " + packetType);
|
||||
Console.log("unknown command: " + packetType);
|
||||
}
|
||||
}
|
||||
|
||||
public static function sendPacketToAll(packetData:haxe.io.BytesOutput) {
|
||||
var bytes = packetData.getBytes();
|
||||
for (c => v in clients) {
|
||||
v.datachannel.sendBytes(packetData.getBytes());
|
||||
v.sendBytes(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,4 +276,10 @@ class Net {
|
|||
var bytes = packetData.getBytes();
|
||||
clientDatachannel.sendBytes(bytes);
|
||||
}
|
||||
|
||||
public static function addDummyConnection() {
|
||||
if (Net.isHost) {
|
||||
addGhost(Net.clientId++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package net;
|
||||
|
||||
import net.Net.GameplayState;
|
||||
import net.ClientConnection.GameplayState;
|
||||
import net.Net.NetPacketType;
|
||||
import gui.MultiplayerLevelSelectGui;
|
||||
import src.MarbleGame;
|
||||
|
|
@ -46,7 +46,7 @@ class NetCommands {
|
|||
@:rpc(server) public static function setStartTime(t:Float) {
|
||||
if (MarbleGame.instance.world != null) {
|
||||
if (Net.isClient) {
|
||||
t -= Net.clientIdMap[0].rtt / 2; // Subtract receving time
|
||||
t -= cast(Net.clientIdMap[0], ClientConnection).rtt / 2; // Subtract receving time
|
||||
}
|
||||
MarbleGame.instance.world.startRealTime = MarbleGame.instance.world.timeState.timeSinceLoad + t;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue