mirror of
https://github.com/EmulatorJS/EmulatorJS.git
synced 2024-09-20 10:56:30 +00:00
Netplay work
This commit is contained in:
parent
4e8d11ece7
commit
6cdf8c714c
3 changed files with 102 additions and 85 deletions
|
@ -29,7 +29,8 @@ class EJS_GameManager {
|
||||||
toggleRewind: this.Module.cwrap('toggle_rewind', 'null', ['number']),
|
toggleRewind: this.Module.cwrap('toggle_rewind', 'null', ['number']),
|
||||||
setRewindGranularity: this.Module.cwrap('set_rewind_granularity', 'null', ['number']),
|
setRewindGranularity: this.Module.cwrap('set_rewind_granularity', 'null', ['number']),
|
||||||
toggleSlowMotion: this.Module.cwrap('toggle_slow_motion', 'null', ['number']),
|
toggleSlowMotion: this.Module.cwrap('toggle_slow_motion', 'null', ['number']),
|
||||||
setSlowMotionRatio: this.Module.cwrap('set_sm_ratio', 'null', ['number'])
|
setSlowMotionRatio: this.Module.cwrap('set_sm_ratio', 'null', ['number']),
|
||||||
|
getFrameNum: this.Module.cwrap('get_current_frame_count', 'number', [''])
|
||||||
}
|
}
|
||||||
this.mkdir("/home");
|
this.mkdir("/home");
|
||||||
this.mkdir("/home/web_user");
|
this.mkdir("/home/web_user");
|
||||||
|
@ -327,6 +328,9 @@ class EJS_GameManager {
|
||||||
setRewindGranularity(value) {
|
setRewindGranularity(value) {
|
||||||
this.functions.setRewindGranularity(value);
|
this.functions.setRewindGranularity(value);
|
||||||
}
|
}
|
||||||
|
getFrameNum() {
|
||||||
|
return this.functions.getFrameNum();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.EJS_GameManager = EJS_GameManager;
|
window.EJS_GameManager = EJS_GameManager;
|
||||||
|
|
Binary file not shown.
171
data/emulator.js
171
data/emulator.js
|
@ -4394,7 +4394,11 @@ class EmulatorJS {
|
||||||
let justReset = false;
|
let justReset = false;
|
||||||
this.netplay.dataMessage = (data) => {
|
this.netplay.dataMessage = (data) => {
|
||||||
//console.log(data);
|
//console.log(data);
|
||||||
|
if (data.sync === true && this.netplay.owner) {
|
||||||
|
this.netplay.sync();
|
||||||
|
}
|
||||||
if (data.state) {
|
if (data.state) {
|
||||||
|
this.netplay.wait = true;
|
||||||
this.netplay.setLoading(true);
|
this.netplay.setLoading(true);
|
||||||
this.pause(true);
|
this.pause(true);
|
||||||
this.gameManager.loadState(new Uint8Array(data.state));
|
this.gameManager.loadState(new Uint8Array(data.state));
|
||||||
|
@ -4409,130 +4413,139 @@ class EmulatorJS {
|
||||||
if (data.ready && this.netplay.owner) {
|
if (data.ready && this.netplay.owner) {
|
||||||
this.netplay.ready++;
|
this.netplay.ready++;
|
||||||
if (this.netplay.ready === this.netplay.getUserCount()) {
|
if (this.netplay.ready === this.netplay.getUserCount()) {
|
||||||
this.netplay.sendMessage({readyready:true, resetCurrentFrame: true});
|
this.netplay.sendMessage({readyready:true});
|
||||||
setTimeout(() => this.play(true), 100);
|
this.netplay.reset();
|
||||||
|
this.play(true);
|
||||||
this.netplay.setLoading(false);
|
this.netplay.setLoading(false);
|
||||||
this.netplay.current_frame = 0;
|
|
||||||
justReset = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.readyready) {
|
if (data.readyready) {
|
||||||
this.netplay.setLoading(false);
|
this.netplay.setLoading(false);
|
||||||
this.netplay.current_frame = 0;
|
this.netplay.reset();
|
||||||
this.play(true)
|
|
||||||
}
|
|
||||||
if (data.resetCurrentFrame) {
|
|
||||||
this.play(true);
|
this.play(true);
|
||||||
this.netplay.current_frame = 0;
|
|
||||||
this.netplay.inputs = {};
|
|
||||||
}
|
}
|
||||||
if (data.user_frame && this.netplay.owner) {
|
if (data.shortPause && data.shortPause !== this.netplay.playerID) {
|
||||||
if (justReset) {
|
|
||||||
justReset = false;
|
|
||||||
this.netplay.current_frame = 0;
|
|
||||||
this.netplay.inputs = {};
|
|
||||||
}
|
|
||||||
this.netplay.users[data.user_frame.user] = data.user_frame.frame;
|
|
||||||
//console.log(data.user_frame.frame, this.netplay.current_frame);
|
|
||||||
}
|
|
||||||
if (data.shortPause === this.netplay.playerID) {
|
|
||||||
this.pause(true);
|
this.pause(true);
|
||||||
setTimeout(() => this.play(true), 5);
|
this.netplay.wait = true;
|
||||||
} else if (data.lessShortPause === this.netplay.playerID) {
|
setTimeout(() => this.play(true), 48);
|
||||||
|
}
|
||||||
|
if (data["sync-control"]) {
|
||||||
|
data["sync-control"].forEach((value) => {
|
||||||
|
let inFrame = parseInt(value.frame);
|
||||||
|
let frame = this.netplay.currentFrame;
|
||||||
|
this.netplay.inputsData[inFrame] || (this.netplay.inputsData[inFrame] = []);
|
||||||
|
if (!value.connected_input || value.connected_input[0] < 0) return;
|
||||||
|
if (inFrame === frame) {
|
||||||
|
this.gameManager.functions.simulateInput(value.connected_input[0], value.connected_input[1], value.connected_input[2]);
|
||||||
|
}
|
||||||
|
this.netplay.inputsData[frame] || (this.netplay.inputsData[frame] = []);
|
||||||
|
if (this.netplay.owner) {
|
||||||
|
this.netplay.inputsData[frame].push(value);
|
||||||
|
this.gameManager.functions.simulateInput(value.connected_input[0], value.connected_input[1], value.connected_input[2]);
|
||||||
|
if (frame - 10 >= inFrame) {
|
||||||
|
this.netplay.wait = true;
|
||||||
this.pause(true);
|
this.pause(true);
|
||||||
setTimeout(() => this.play(true), 10);
|
setTimeout(() => {
|
||||||
|
this.play(true);
|
||||||
|
this.netplay.wait = false;
|
||||||
|
}, 48)
|
||||||
}
|
}
|
||||||
if (data.input && this.netplay.owner) {
|
} else {
|
||||||
this.netplay.simulateInput(this.netplay.getUserIndex(data.user), data.input[0], data.input[1], true);
|
this.netplay.inputsData[inFrame].push(value);
|
||||||
|
if (this.netplay.inputsData[frame]) {
|
||||||
|
this.play(true);
|
||||||
}
|
}
|
||||||
if (data.connected_input && !this.netplay.owner) {
|
if (frame + 10 <= inFrame && inFrame > this.netplay.init_frame + 100) {
|
||||||
if (!this.netplay.inputs[data.frame]) {
|
this.netplay.sendMessage({shortPause:this.netplay.playerID});
|
||||||
this.netplay.inputs[data.frame] = [];
|
|
||||||
}
|
}
|
||||||
this.netplay.inputs[data.frame].push([data.connected_input[0], data.connected_input[1], data.connected_input[2]]);
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (data.restart) {
|
if (data.restart) {
|
||||||
this.gameManager.restart();
|
this.gameManager.restart();
|
||||||
this.netplay.current_frame = 0;
|
this.netplay.reset();
|
||||||
this.netplay.inputs = {};
|
|
||||||
this.play(true);
|
this.play(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.netplay.simulateInput = (player, index, value, resp) => {
|
this.netplay.simulateInput = (player, index, value, resp) => {
|
||||||
if (!this.isNetplay) return;
|
if (!this.isNetplay) return;
|
||||||
if (player !== 0 && !resp) return;
|
if (player !== 0 && !resp) return;
|
||||||
|
player = this.netplay.getUserIndex(this.netplay.playerID)
|
||||||
|
const frame = this.netplay.currentFrame;
|
||||||
if (this.netplay.owner) {
|
if (this.netplay.owner) {
|
||||||
const frame = this.netplay.current_frame;
|
if (!this.netplay.inputsData[frame]) {
|
||||||
this.gameManager.functions.simulateInput(player, index, value);
|
this.netplay.inputsData[frame] = [];
|
||||||
this.netplay.sendMessage({
|
}
|
||||||
|
this.netplay.inputsData[frame].push({
|
||||||
frame: frame,
|
frame: frame,
|
||||||
connected_input: [player, index, value]
|
connected_input: [player, index, value]
|
||||||
});
|
})
|
||||||
|
this.gameManager.functions.simulateInput(player, index, value);
|
||||||
} else {
|
} else {
|
||||||
this.netplay.sendMessage({
|
this.netplay.sendMessage({
|
||||||
user: this.netplay.playerID,
|
"sync-control": [{
|
||||||
input: [index, value]
|
frame: frame,
|
||||||
});
|
connected_input: [player, index, value]
|
||||||
|
}]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.netplay.sendMessage = (data) => {
|
this.netplay.sendMessage = (data) => {
|
||||||
this.netplay.socket.emit("data-message", data);
|
this.netplay.socket.emit("data-message", data);
|
||||||
}
|
}
|
||||||
|
this.netplay.reset = () => {
|
||||||
|
this.netplay.init_frame = this.netplay.currentFrame;
|
||||||
|
this.netplay.inputsData = {};
|
||||||
|
}
|
||||||
//let fps;
|
//let fps;
|
||||||
//let lastTime;
|
//let lastTime;
|
||||||
|
this.netplay.init_frame = 0;
|
||||||
|
this.netplay.currentFrame = 0;
|
||||||
|
this.netplay.inputsData = {};
|
||||||
this.Module.postMainLoop = () => {
|
this.Module.postMainLoop = () => {
|
||||||
//const newTime = window.performance.now();
|
//const newTime = window.performance.now();
|
||||||
//fps = 1000 / (newTime - lastTime);
|
//fps = 1000 / (newTime - lastTime);
|
||||||
//console.log(fps);
|
//console.log(fps);
|
||||||
//lastTime = newTime;
|
//lastTime = newTime;
|
||||||
if (!this.isNetplay || this.paused) return;
|
|
||||||
this.netplay.current_frame++;
|
//frame syncing - working
|
||||||
|
//control syncing - broken
|
||||||
|
if (!this.isNetplay) return;
|
||||||
|
this.netplay.currentFrame = parseInt(this.gameManager.getFrameNum()) - this.netplay.init_frame;
|
||||||
if (this.netplay.owner) {
|
if (this.netplay.owner) {
|
||||||
for (const k in this.netplay.users) {
|
let to_send = [];
|
||||||
if (this.netplay.getUserIndex(k) === -1) {
|
for (let i=this.netplay.currentFrame-1; i<this.netplay.currentFrame; i++) {
|
||||||
delete this.netplay.users[k];
|
this.netplay.inputsData[i] ? this.netplay.inputsData[i].forEach((value) => {
|
||||||
continue;
|
to_send.push(value);
|
||||||
}
|
}) : to_send.push({frame: i});
|
||||||
const diff = this.netplay.current_frame - this.netplay.users[k];
|
|
||||||
//console.log(diff);
|
|
||||||
if (Math.abs(diff) > 75) {
|
|
||||||
this.netplay.sync();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//this'll be adjusted if needed
|
|
||||||
if (diff < 0) {
|
|
||||||
this.netplay.sendMessage({
|
|
||||||
lessShortPause: k
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (diff < 5) {
|
|
||||||
this.netplay.sendMessage({
|
|
||||||
shortPause: k
|
|
||||||
})
|
|
||||||
} else if (diff > 30) {
|
|
||||||
this.pause(true);
|
|
||||||
setTimeout(() => this.play(true), 10);
|
|
||||||
} else if (diff > 10) {
|
|
||||||
this.pause(true);
|
|
||||||
setTimeout(() => this.play(true), 5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
this.netplay.sendMessage({"sync-control": to_send});
|
||||||
} else {
|
} else {
|
||||||
this.netplay.sendMessage({
|
if (this.netplay.currentFrame <= 0 || this.netplay.inputsData[this.netplay.currentFrame]) {
|
||||||
user_frame: {
|
this.netplay.wait = false;
|
||||||
user: this.netplay.playerID,
|
this.play();
|
||||||
frame: this.netplay.current_frame
|
this.netplay.inputsData[this.netplay.currentFrame].forEach((value) => {
|
||||||
}
|
console.log(value);
|
||||||
});
|
if (!value.connected_input) return;
|
||||||
for (const k in this.netplay.inputs) {
|
this.gameManager.functions.simulateInput(value.connected_input[0], value.connected_input[1], value.connected_input[2]);
|
||||||
if (k <= this.netplay.current_frame) {
|
|
||||||
this.netplay.inputs[k].forEach(data => {
|
|
||||||
this.gameManager.functions.simulateInput(data[0], data[1], data[2]);
|
|
||||||
})
|
})
|
||||||
delete this.netplay.inputs[k];
|
} else if (!this.netplay.syncing) {
|
||||||
|
console.log("sync");
|
||||||
|
this.pause(true);
|
||||||
|
this.netplay.sendMessage({sync:true});
|
||||||
|
this.netplay.syncing = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.netplay.currentFrame % 100 === 0) {
|
||||||
|
Object.keys(this.netplay.inputsData).forEach(value => {
|
||||||
|
if (value < this.netplay.currentFrame - 50) {
|
||||||
|
this.netplay.inputsData[value] = null;
|
||||||
|
delete this.netplay.inputsData[value];
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.netplay.updateList = {
|
this.netplay.updateList = {
|
||||||
|
|
Loading…
Reference in a new issue