diff --git a/Client/options/operagx/options_operagx.yy b/Client/options/operagx/options_operagx.yy index bb157d5..36530da 100644 --- a/Client/options/operagx/options_operagx.yy +++ b/Client/options/operagx/options_operagx.yy @@ -7,7 +7,7 @@ }, "option_operagx_display_cursor": true, "option_operagx_editUrl": "", - "option_operagx_game_name": "${project_name}", + "option_operagx_game_name": "Client", "option_operagx_guid": "", "option_operagx_internalShareUrl": "", "option_operagx_interpolate_pixels": true, diff --git a/JavascriptServer/internal/concepts/client.js b/JavascriptServer/internal/concepts/client.js index 7e203e4..02032d8 100644 --- a/JavascriptServer/internal/concepts/client.js +++ b/JavascriptServer/internal/concepts/client.js @@ -15,25 +15,35 @@ import MatchMaker from '#util/matchmaker'; // this is a wrapper around sockets export default class Client extends SendStuff { name = ''; - socket = null; /** @type {import('ws').WebSocket | import('net').Socket} */ - type; /** @type {'ws' | 'tcp'} */ + /** @type {import('ws').WebSocket | import('net').Socket} */ + socket = null; + /** @type {'ws' | 'tcp'} */ + type; ip; - lobby = null; /** @type {Lobby} */ - room = null; /** @type {Room} */ - party = null; /** @type {Party} */ + /** @type {Lobby} */ + lobby = null; + /** @type {Room} */ + room = null; + /** @type {Party} */ + party = null; party_invites = []; - account = null; /** @type {Account} */ - profile = null; /** @type {Profile} */ + /** @type {Account} */ + account = null; + /** @type {Profile} */ + profile = null; // used internally in packet.ts - halfpack; /** @type {Buffer} */ + /** @type {Buffer} */ + halfpack; - entity = null; /** @type {PlayerEntity} */ + /** @type {PlayerEntity} */ + entity = null; - ping; /** @type {number} */ + /** @type {number} */ + ping; room_join_timer = -1; // if >0 - joined recently @@ -272,6 +282,10 @@ export default class Client extends SendStuff { } } + /** + * @param {Client|IProfile} user_to + * @returns {Promise} + */ async friendRequestSend(user_to) { user_to = user_to instanceof Client ? user_to.profile : user_to; if (!this.logged_in) @@ -283,6 +297,11 @@ export default class Client extends SendStuff { return await FriendRequest.create({ sender, receiver }); } + /** + * @param {Client|IProfile} user_from + * @param {Client|IProfile} user_to + * @returns {Promise} + */ async friendRequestFind(user_from, user_to) { user_from = user_from instanceof Client ? user_from.profile : user_from; user_to = user_to instanceof Client ? user_to.profile : user_to; @@ -290,6 +309,9 @@ export default class Client extends SendStuff { return await FriendRequest.findRequestId(user_from._id, user_to._id); } + /** + * @param {Client|IProfile} user_from + */ async friendRequestAccept(user_from) { user_from = user_from instanceof Client ? user_from.profile : user_from; if (!this.logged_in) @@ -302,6 +324,9 @@ export default class Client extends SendStuff { } } + /** + * @param {Client|IProfile} user_from + */ async friendRequestReject(user_from) { user_from = user_from instanceof Client ? user_from.profile : user_from; if (!this.logged_in) @@ -314,6 +339,9 @@ export default class Client extends SendStuff { } } + /** + * @param {Client|IProfile} user_to + */ async friendRequestCancel(user_to) { user_to = user_to instanceof Client ? user_to.profile : user_to; if (!this.logged_in) @@ -326,6 +354,9 @@ export default class Client extends SendStuff { } } + /** + * @param {Client|IProfile} friend + */ async friendRemove(friend) { friend = friend instanceof Client ? friend.profile : friend; if (!this.logged_in) @@ -340,7 +371,6 @@ export default class Client extends SendStuff { } - partyCreate() { if (this.party) this.partyLeave(); @@ -363,6 +393,9 @@ export default class Client extends SendStuff { this.sendPartyInviteSent(); } + /** + * @param {string} partyid + */ partyJoin(partyid) { let party = partyGet(partyid); party.addMember(this); diff --git a/JavascriptServer/internal/concepts/lobby.js b/JavascriptServer/internal/concepts/lobby.js index 11851d9..b9c2d1b 100644 --- a/JavascriptServer/internal/concepts/lobby.js +++ b/JavascriptServer/internal/concepts/lobby.js @@ -45,9 +45,11 @@ export function lobbyList() { // in context of an MMO this is a shard/separated world export default class Lobby extends EventEmitter { - lobbyid = "-1"; // assigned when created + lobbyid = '-1'; // assigned when created status = 'open'; + /** @type {Client[]} */ players = []; + /** @type {Room[]} */ rooms = []; max_players = global.config.lobby.max_players || undefined; // smells like Java @@ -66,6 +68,10 @@ export default class Lobby extends EventEmitter { } } + /** + * @param {Client} player + * @returns {void|-1} + */ addPlayer(player) { if (this.full) { trace('warning: can\'t add a player - the lobby is full!'); @@ -101,6 +107,11 @@ export default class Lobby extends EventEmitter { } } + /** + * @param {Client} player + * @param {string?} reason + * @param {boolean?} forced + */ kickPlayer(player, reason, forced) { var idx = this.players.indexOf(player); this.players.splice(idx, 1); @@ -115,6 +126,9 @@ export default class Lobby extends EventEmitter { } } + /** + * @param {Client} player + */ addIntoPlay(player) { if (player.lobby === this) { player.onPlay(); @@ -124,10 +138,17 @@ export default class Lobby extends EventEmitter { } } + /** + * @param {string} room_name + * @returns {Room} room + */ findRoomByMapName(room_name) { return this.rooms.find(r => r.map.name === room_name); } + /** + * @param {object} data + */ broadcast(data) { this.players.forEach(function (player) { player.write(data); @@ -142,7 +163,7 @@ export default class Lobby extends EventEmitter { } close() { - // kick all plaayers + // kick all players this.players.forEach((player) => this.kickPlayer(player, 'lobby is closing!', true)); this.status = 'closed'; } diff --git a/JavascriptServer/internal/schemas/account.js b/JavascriptServer/internal/schemas/account.js index f65d76d..3b79f49 100644 --- a/JavascriptServer/internal/schemas/account.js +++ b/JavascriptServer/internal/schemas/account.js @@ -1,7 +1,8 @@ // this section contains a schema for saving players' account info import trace from '#util/logging'; -import { model, Schema } from 'mongoose'; +import mongoose from 'mongoose'; +const { model, Schema } = mongoose; import { hashPassword, verifyPassword } from '#util/password_encryption'; // you can edit this schema! diff --git a/JavascriptServer/internal/schemas/friend_request.js b/JavascriptServer/internal/schemas/friend_request.js index 9be0ee3..6923255 100644 --- a/JavascriptServer/internal/schemas/friend_request.js +++ b/JavascriptServer/internal/schemas/friend_request.js @@ -1,8 +1,5 @@ -import { createRequire } from 'module'; -const require = createRequire(import.meta.url); - -const mongoose = require('mongoose'); -const { Schema, model } = mongoose; +import mongoose from 'mongoose'; +const { model, Schema } = mongoose; import Profile from '#schemas/profile'; const friendRequestSchema = new Schema({ @@ -41,5 +38,5 @@ friendRequestSchema.statics.cancel = async function (req_id) { await FriendRequest.findByIdAndDelete(req_id); }; -export const FriendRequest = new model('FriendRequest', friendRequestSchema); +export const FriendRequest = model('FriendRequest', friendRequestSchema); export default FriendRequest; diff --git a/JavascriptServer/internal/schemas/profile.js b/JavascriptServer/internal/schemas/profile.js index 1d8f2f9..b6daa38 100644 --- a/JavascriptServer/internal/schemas/profile.js +++ b/JavascriptServer/internal/schemas/profile.js @@ -1,5 +1,6 @@ // This schema is for profiles -import { Schema, model } from 'mongoose'; +import mongoose from 'mongoose'; +const { model, Schema } = mongoose; // this holds the state of the profile // you can edit this schema! diff --git a/JavascriptServer/jsconfig.json b/JavascriptServer/jsconfig.json new file mode 100644 index 0000000..f995e4e --- /dev/null +++ b/JavascriptServer/jsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "paths": { + "#schemas/*": ["internal/schemas/*"], + "#entity/*": ["internal/entities/entity_types/*"], + "#entities/*": ["internal/entities/*"], + "#initializers/*": ["internal/initializers/*"], + "#types/*": ["internal/types/*"], + "#concepts/*": ["internal/concepts/*"], + "#util/*": ["internal/util/*"], + + "#custom/*": ["custom/*"], + "#internal/*": ["internal/*"], + + "#root/*": ["./*"], + + "*": ["node_modules/*", "src/*"] + } + } +} \ No newline at end of file diff --git a/Release/GMClient.zip b/Release/GMClient.zip index 7787e90..d2799b1 100644 Binary files a/Release/GMClient.zip and b/Release/GMClient.zip differ diff --git a/Release/JSServer.zip b/Release/JSServer.zip index 5ca4775..69828b6 100644 Binary files a/Release/JSServer.zip and b/Release/JSServer.zip differ diff --git a/Release/TSServer.zip b/Release/TSServer.zip index dad436d..0b818ba 100644 Binary files a/Release/TSServer.zip and b/Release/TSServer.zip differ diff --git a/Release/Warp.yymps b/Release/Warp.yymps index 7787e90..d2799b1 100644 Binary files a/Release/Warp.yymps and b/Release/Warp.yymps differ diff --git a/TypescriptServer/jsconfig.json b/TypescriptServer/jsconfig.json new file mode 100644 index 0000000..f995e4e --- /dev/null +++ b/TypescriptServer/jsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "paths": { + "#schemas/*": ["internal/schemas/*"], + "#entity/*": ["internal/entities/entity_types/*"], + "#entities/*": ["internal/entities/*"], + "#initializers/*": ["internal/initializers/*"], + "#types/*": ["internal/types/*"], + "#concepts/*": ["internal/concepts/*"], + "#util/*": ["internal/util/*"], + + "#custom/*": ["custom/*"], + "#internal/*": ["internal/*"], + + "#root/*": ["./*"], + + "*": ["node_modules/*", "src/*"] + } + } +} \ No newline at end of file diff --git a/TypescriptServer/src/internal/concepts/client.ts b/TypescriptServer/src/internal/concepts/client.ts index 5bc4d68..1e529ad 100644 --- a/TypescriptServer/src/internal/concepts/client.ts +++ b/TypescriptServer/src/internal/concepts/client.ts @@ -29,25 +29,35 @@ export type ClientInfo = { // this is a wrapper around sockets export default class Client extends SendStuff implements IClient { name: string = ''; - socket: Sock = null; /** @type {import('ws').WebSocket | import('net').Socket} */ - type: SockType; /** @type {'ws' | 'tcp'} */ + /** @type {import('ws').WebSocket | import('net').Socket} */ + socket: Sock = null; + /** @type {'ws' | 'tcp'} */ + type: SockType; ip: string; - lobby: Lobby = null; /** @type {Lobby} */ - room: Room = null; /** @type {Room} */ - party: Party = null; /** @type {Party} */ + /** @type {Lobby} */ + lobby: Lobby = null; + /** @type {Room} */ + room: Room = null; + /** @type {Party} */ + party: Party = null; party_invites: string[] = []; - account: IAccount = null; /** @type {Account} */ - profile: IProfile = null; /** @type {Profile} */ + /** @type {Account} */ + account: IAccount = null; + /** @type {Profile} */ + profile: IProfile = null; // used internally in packet.ts - halfpack: Buffer; /** @type {Buffer} */ + /** @type {Buffer} */ + halfpack: Buffer; - entity: PlayerEntity = null; /** @type {PlayerEntity} */ + /** @type {PlayerEntity} */ + entity: PlayerEntity = null; - ping: number; /** @type {number} */ + /** @type {number} */ + ping: number; room_join_timer: number = -1; // if >0 - joined recently @@ -283,6 +293,10 @@ export default class Client extends SendStuff implements IClient { } } + /** + * @param {Client|IProfile} user_to + * @returns {Promise} + */ async friendRequestSend(user_to:Client|IProfile):Promise { user_to = user_to instanceof Client ? user_to.profile : user_to; if (!this.logged_in) return null; @@ -293,6 +307,11 @@ export default class Client extends SendStuff implements IClient { return await FriendRequest.create({ sender, receiver }); } + /** + * @param {Client|IProfile} user_from + * @param {Client|IProfile} user_to + * @returns {Promise} + */ private async friendRequestFind(user_from:Client|IProfile, user_to:Client|IProfile) { user_from = user_from instanceof Client ? user_from.profile : user_from; user_to = user_to instanceof Client ? user_to.profile : user_to; @@ -300,6 +319,9 @@ export default class Client extends SendStuff implements IClient { return await FriendRequest.findRequestId(user_from._id, user_to._id); } + /** + * @param {Client|IProfile} user_from + */ async friendRequestAccept(user_from:Client|IProfile) { user_from = user_from instanceof Client ? user_from.profile : user_from; if (!this.logged_in) return; @@ -311,6 +333,9 @@ export default class Client extends SendStuff implements IClient { } } + /** + * @param {Client|IProfile} user_from + */ async friendRequestReject(user_from:Client|IProfile) { user_from = user_from instanceof Client ? user_from.profile : user_from; if (!this.logged_in) return; @@ -322,6 +347,9 @@ export default class Client extends SendStuff implements IClient { } } + /** + * @param {Client|IProfile} user_to + */ async friendRequestCancel(user_to:Client|IProfile) { user_to = user_to instanceof Client ? user_to.profile : user_to; if (!this.logged_in) return null; @@ -333,6 +361,9 @@ export default class Client extends SendStuff implements IClient { } } + /** + * @param {Client|IProfile} friend + */ async friendRemove(friend:Client|IProfile) { friend = friend instanceof Client ? friend.profile : friend; if (!this.logged_in) return; @@ -346,7 +377,6 @@ export default class Client extends SendStuff implements IClient { } - partyCreate() { if (this.party) this.partyLeave(); @@ -367,6 +397,9 @@ export default class Client extends SendStuff implements IClient { this.sendPartyInviteSent(); } + /** + * @param {string} partyid + */ partyJoin(partyid: string) { let party = partyGet(partyid); party.addMember(this); diff --git a/TypescriptServer/src/internal/concepts/lobby.ts b/TypescriptServer/src/internal/concepts/lobby.ts index 6e1761f..c1f5fe2 100644 --- a/TypescriptServer/src/internal/concepts/lobby.ts +++ b/TypescriptServer/src/internal/concepts/lobby.ts @@ -69,9 +69,11 @@ export function lobbyList():Lobby[] { // in context of an MMO this is a shard/separated world export default class Lobby extends EventEmitter { - lobbyid:string = "-1"; // assigned when created + lobbyid:string = '-1'; // assigned when created status:LobbyStatus = 'open'; + /** @type {Client[]} */ players:Client[] = []; + /** @type {Room[]} */ rooms:Room[] = []; max_players:number = global.config.lobby.max_players || undefined; // smells like Java @@ -90,6 +92,10 @@ export default class Lobby extends EventEmitter { } } + /** + * @param {Client} player + * @returns {void|-1} + */ addPlayer(player:Client):void|-1 { if (this.full) { trace('warning: can\'t add a player - the lobby is full!'); @@ -125,6 +131,11 @@ export default class Lobby extends EventEmitter { } } + /** + * @param {Client} player + * @param {string?} reason + * @param {boolean?} forced + */ kickPlayer(player:Client, reason?:string, forced?:boolean):void { var idx = this.players.indexOf(player); this.players.splice(idx, 1); @@ -139,6 +150,9 @@ export default class Lobby extends EventEmitter { } } + /** + * @param {Client} player + */ addIntoPlay(player:Client):void { if (player.lobby === this) { player.onPlay(); @@ -148,10 +162,17 @@ export default class Lobby extends EventEmitter { } } - findRoomByMapName(room_name:string) { + /** + * @param {string} room_name + * @returns {Room} room + */ + findRoomByMapName(room_name:string):Room { return this.rooms.find(r => r.map.name === room_name); } + /** + * @param {object} data + */ broadcast(data:object):void { this.players.forEach(function(player) { player.write(data); @@ -166,7 +187,7 @@ export default class Lobby extends EventEmitter { } close():void { - // kick all plaayers + // kick all players this.players.forEach((player) => this.kickPlayer(player, 'lobby is closing!', true)); this.status = 'closed'; } diff --git a/TypescriptServer/src/internal/schemas/account.ts b/TypescriptServer/src/internal/schemas/account.ts index 86f097c..3488d71 100644 --- a/TypescriptServer/src/internal/schemas/account.ts +++ b/TypescriptServer/src/internal/schemas/account.ts @@ -1,7 +1,8 @@ // this section contains a schema for saving players' account info import trace from '#util/logging'; -import { Model, model, Document, ObjectId, Schema } from 'mongoose'; +import mongoose, { ObjectId, Document, Model } from 'mongoose'; +const { model, Schema } = mongoose; import { hashPassword, verifyPassword } from '#util/password_encryption'; diff --git a/TypescriptServer/src/internal/schemas/friend_request.ts b/TypescriptServer/src/internal/schemas/friend_request.ts index c3d4906..b11ac83 100644 --- a/TypescriptServer/src/internal/schemas/friend_request.ts +++ b/TypescriptServer/src/internal/schemas/friend_request.ts @@ -1,10 +1,5 @@ -import { createRequire } from 'module'; -const require = createRequire(import.meta.url); - -const mongoose = require('mongoose'); - -import { Model, Document, ObjectId } from 'mongoose'; -const { Schema, model } = mongoose; +import mongoose, { Model, Document, ObjectId } from 'mongoose'; +const { model, Schema } = mongoose; import { Account, IAccount } from '#schemas/account'; import Profile, { IProfile } from '#schemas/profile'; @@ -61,5 +56,5 @@ friendRequestSchema.statics.cancel = async function(req_id:OID):Promise { await FriendRequest.findByIdAndDelete(req_id); } -export const FriendRequest:IFriendRequestModel = new model('FriendRequest', friendRequestSchema); +export const FriendRequest:IFriendRequestModel = model('FriendRequest', friendRequestSchema); export default FriendRequest; \ No newline at end of file diff --git a/TypescriptServer/src/internal/schemas/profile.ts b/TypescriptServer/src/internal/schemas/profile.ts index e2a9fd7..aa56ab0 100644 --- a/TypescriptServer/src/internal/schemas/profile.ts +++ b/TypescriptServer/src/internal/schemas/profile.ts @@ -1,5 +1,6 @@ // This schema is for profiles -import { Schema, model, Document, ObjectId, Model } from 'mongoose'; +import mongoose, { Document, ObjectId, Model } from 'mongoose'; +const { model, Schema } = mongoose; import { Account, IAccount } from '#schemas/account'; export interface IProfile extends Document {