Skip to content

Commit

Permalink
- Reldens - v4.0.0-beta.35
Browse files Browse the repository at this point in the history
- Merge pull request #244 from damian-pastorini/v4.0.0-beta.35
  • Loading branch information
damian-pastorini committed Jun 4, 2024
2 parents 12e3a38 + 778f22d commit 468257d
Show file tree
Hide file tree
Showing 148 changed files with 11,409 additions and 20,761 deletions.
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
[![Reldens - GitHub - Release](https://www.dwdeveloper.com/media/reldens/reldens-mmorpg-platform.png)](https://github.com/damian-pastorini/reldens)
<div style="width: 100%; background-color: #000000; text-align: center;">
<a href="https://github.com/damian-pastorini/reldens">
<img alt="Reldens - You can make it" src="https://www.dwdeveloper.com/media/reldens/reldens-mmorpg-platform.png"/>
</a>
</div>

---

<div style="text-align: center">
<a href="https://discord.gg/HuJMxUY">
<h3>Join our Discord community!</h3>
<img alt="Reldens - Discord" src="https://img.shields.io/badge/discord-%235865F2?style=for-the-badge&logo=discord&logoColor=white"/>
</a>
</div>

---

# [Reldens - MMORPG Platform](https://www.reldens.com/)

Welcome to Reldens, the MMORPG Platform designed to empower developers in creating multiplayer games.
Welcome to Reldens, a platform designed to empower developers in creating multiplayer games.

With a wide array of features, Reldens enables developers to craft a rich gaming experience without grappling with the complexities usually associated with making a multiplayer game secure and efficient over any network.

Expand All @@ -24,7 +37,7 @@ While the current stage of the platform is tailored for developers, ongoing impr
As for the latest version released the platform will provide you with the following features.

- Installation GUI: Easy to install through the web.
- Administration Panel: Manage every single aspect of your game through the panel. Hot-plugs are a key feature and a work in progress.
- Administration Panel: Manage every single aspect of your game through the panel (WIP, temporally disabled).
- Trade System: Between Players (trade) and NPCs (buy and sell).
- Full In-game Chat: Global, by room, and private messages between users with chat types and split in tabs.
- Player Stats: Fully configurable stats! HP? MP? Magic? Stamina, you can set up as much as you need for your game logic.
Expand All @@ -40,8 +53,9 @@ As for the latest version released the platform will provide you with the follow
- Minimap: Optional configurable minimap.
- Configurable Visible Players Name and Life-bars.
- Terms and Conditions: Ready to be set up as you need.
- Guest Users.
- Users Registration: Continue playing later and double login invalidation.
- Multiple Players Creation
- Multiple Players Creation.
- Registration and Login Integrated with Firebase.
- Database Ready: With multiple drivers for different storage or using MySQL by default all you need will be saved.

Expand Down
147 changes: 108 additions & 39 deletions bin/generate.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,63 @@
#! /usr/bin/env node

const fs = require('fs');
const path = require('path');
const {
PlayersExperiencePerLevel,
MonstersExperiencePerLevel,
AttributesPerLevel
} = require('@reldens/game-data-generator');
const {
RandomMapGenerator,
LayerElementsObjectLoader,
LayerElementsCompositeLoader,
MultipleByLoaderGenerator,
MultipleWithAssociationsByLoaderGenerator
} = require("@reldens/tile-map-generator");
const { FileHandler } = require('../lib/game/server/file-handler');
const path = require("path");
const {Logger} = require("@reldens/utils");

let args = process.argv;
if(2 === args.length){
console.error('- Missing arguments.', args);
return false;
/**
*
* Commands:
*
* $ npx reldens-generate players-experience-per-level ./generate-data/players-experience-per-level.json
*
* $ npx reldens-generate monsters-experience-per-level ./generate-data/monsters-experience-per-level.json ./generate-data/players-level-sample.json
*
* $ npx reldens-generate attributes-per-level ./generate-data/attributes-per-level.json
*
* $ npx reldens-generate maps ./generate-data/map-data.json LayerElementsObjectLoader
*
* $ npx reldens-generate maps ./generate-data/map-composite-data.json LayerElementsCompositeLoader
*
* $ npx reldens-generate maps ./generate-data/map-composite-data-with-names.json MultipleByLoaderGenerator
*
* $ RELDENS_LOG_LEVEL=9 npx reldens-generate maps ./generate-data/map-composite-data-with-associations.json MultipleWithAssociationsByLoaderGenerator
*
*/

let mapsGenerateModes = {
LayerElementsObjectLoader: async (commandParams) => {
const loader = new LayerElementsObjectLoader(commandParams);
await loader.load();
const generator = new RandomMapGenerator(loader.mapData);
return await generator.generate();
},
LayerElementsCompositeLoader: async (commandParams) => {
const loader = new LayerElementsCompositeLoader(commandParams);
await loader.load();
const generator = new RandomMapGenerator();
await generator.fromElementsProvider(loader.mapData);
return await generator.generate();
},
MultipleByLoaderGenerator: async (commandParams) => {
let generator = new MultipleByLoaderGenerator({loaderData: commandParams});
await generator.generate();
},
MultipleWithAssociationsByLoaderGenerator: async (commandParams) => {
let generator = new MultipleWithAssociationsByLoaderGenerator({loaderData: commandParams});
await generator.generate();
}
}

let validCommands = {
Expand All @@ -26,35 +72,31 @@ let validCommands = {
'attributes-per-level': (commandParams) => {
let attributesPerLevel = new AttributesPerLevel(commandParams);
attributesPerLevel.generate();
},
'maps': async (commandParams) => {
if (!mapsGenerateModes[commandParams.importMode]) {
console.error('- Invalid import mode. Valid options: '+Object.keys(mapsGenerateModes).join(', '));
}
let pathParts = commandParams.mapDataFile.split('/');
commandParams.mapDataFile = pathParts.pop();
commandParams.rootFolder = FileHandler.joinPaths(process.cwd(), ...pathParts);
// @TODO - BETA - Fix the generated folder placement.
// this will generate everything under rootFolder/whatever-the-path-is/generated:
await mapsGenerateModes[commandParams.importMode](commandParams);
let generatedFolder = FileHandler.joinPaths(commandParams.rootFolder, 'generated');
// we need to move the generated data to rootFolder/generated:
FileHandler.copyFolderSync(
generatedFolder,
FileHandler.joinPaths(process.cwd(), 'generated')
);
// FileHandler.removeFolder(generatedFolder);
}
};

function fetchFileContents(filePath)
{
if (!filePath) {
console.error('- Missing data file.', filePath);
return false;
}

let relativePath = path.join(process.cwd(), filePath);
if (!relativePath) {
console.error('- Invalid data file path.', process.cwd(), filePath);
return false;
}

let fileContent = fs.readFileSync(relativePath, {encoding: 'utf8', flag:'r'});
if (!fileContent) {
console.error('- Can not read data file or file empty.', relativePath);
return false;
}

let importedJson = JSON.parse(fileContent);
if (!importedJson) {
console.error('- Can not parse data file.');
return false;
}

return importedJson;
let args = process.argv;
if(2 === args.length){
console.error('- Missing arguments.', args);
return false;
}

let extractedParams = args.slice(2);
Expand All @@ -70,16 +112,43 @@ if (-1 === Object.keys(validCommands).indexOf(command)) {
return false;
}

let importedJson = fetchFileContents(extractedParams[1] || '');
let importJson = 'monsters-experience-per-level' === command
|| 'players-experience-per-level' === command
|| 'attributes-per-level' === command;

if ('monsters-experience-per-level' === command) {
let importedPlayerLevelsJson = fetchFileContents(extractedParams[2] || '');
if (!importedPlayerLevelsJson) {
console.error('- Can not parse data file for player levels.');
if (importJson) {
let filePath = path.join(process.cwd(), extractedParams[1] || '');
if(!filePath){
Logger.error('Invalid data file path.', process.cwd(), filePath);
return false;
}
let importedJson = FileHandler.fetchFileJson(filePath);
if (!importedJson) {
console.error('- Can not parse data file.');
return false;
}
if ('monsters-experience-per-level' === command) {
let secondaryFilePath = path.join(process.cwd(), extractedParams[2] || '');
if(!secondaryFilePath){
Logger.error('Invalid data file path.', process.cwd(), secondaryFilePath);
return false;
}
let importedPlayerLevelsJson = FileHandler.fetchFileJson(secondaryFilePath);
if (!importedPlayerLevelsJson) {
console.error('- Can not parse data file for player levels.');
return false;
}

importedJson.levelsExperienceByKey = importedPlayerLevelsJson;
importedJson.levelsExperienceByKey = importedPlayerLevelsJson;
}
return validCommands[command](importedJson);
}

validCommands[command](importedJson);

if ('maps' === command) {
return validCommands[command]({
mapDataFile: extractedParams[1],
// mapData: fetchFileContents(extractedParams[1] || ''),
importMode: extractedParams[2] || ''
});
}
66 changes: 32 additions & 34 deletions bin/import.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
#! /usr/bin/env node

const fs = require('fs');
const path = require('path');
const { ServerManager } = require('../server');
const { PlayersExperiencePerLevelImporter } = require('../lib/import/server/players-experience-per-level-importer');
const { AttributesPerLevelImporter } = require('../lib/import/server/attributes-per-level-importer');
const { ClassPathsImporter } = require('../lib/import/server/class-paths-importer');
const { MapsImporter } = require('../lib/import/server/maps-importer');
const { SkillsImporter } = require('../lib/import/server/skills-importer');
const { FileHandler } = require('../lib/game/server/file-handler');

let args = process.argv;
if(2 === args.length){
console.error('- Missing arguments.', args);
return false;
}
/**
*
* Commands:
*
* - Players experience per level import is not required if class-paths importer is going to be used.
* $ npx reldens-import players-experience-per-level custom-game-theme-test generate-data/players-experience-per-level.json
*
* - Class-paths importer will also import the experience per level.
* $ npx reldens-import class-paths custom-game-theme-test generate-data/class-paths.json
*
* $ npx reldens-import attributes-per-level custom-game-theme-test generate-data/class-paths-attributes-per-level.json
*
* $ npx reldens-import maps custom-game-theme-test generate-data/maps.json
*
* $ npx reldens-import skills custom-game-theme-test generate-data/skills-data.json
*
*/

let validCommands = {
'players-experience-per-level': async (data, projectThemeName) => {
Expand Down Expand Up @@ -46,6 +58,14 @@ let validCommands = {
}
let importer = new MapsImporter(serverManager);
await importer.import(data);
},
'skills': async (data, projectThemeName) => {
let serverManager = await initializeServer(data, projectThemeName);
if (!serverManager) {
return false;
}
let importer = new SkillsImporter(serverManager);
await importer.import(data);
}
};

Expand All @@ -63,32 +83,10 @@ async function initializeServer(data, projectThemeName)
return appServer;
}

function fetchFileContents(filePath)
{
if (!filePath) {
console.error('- Missing data file.', filePath);
return false;
}

let relativePath = path.join(process.cwd(), filePath);
if (!relativePath) {
console.error('- Invalid data file path.', process.cwd(), filePath);
return false;
}

let fileContent = fs.readFileSync(relativePath, {encoding: 'utf8', flag:'r'});
if (!fileContent) {
console.error('- Can not read data file or file empty.', relativePath);
return false;
}

let importedJson = JSON.parse(fileContent);
if (!importedJson) {
console.error('- Can not parse data file.');
return false;
}

return importedJson;
let args = process.argv;
if(2 === args.length){
console.error('- Missing arguments.', args);
return false;
}

let extractedParams = args.slice(2);
Expand All @@ -110,7 +108,7 @@ if (-1 === Object.keys(validCommands).indexOf(command)) {
return false;
}

validCommands[command](fetchFileContents(extractedParams[2] || ''), themeName).then(() => {
validCommands[command](FileHandler.fetchFileJson(extractedParams[2] || ''), themeName).then(() => {
console.log('Done.');
process.exit();
}).catch((error) => {
Expand Down
6 changes: 6 additions & 0 deletions install/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ <h3 class="form-title">- App -</h3>
<label for="app-port">Port</label>
<input type="text" name="app-port" id="app-port" value="{{app-port}}" class="required" required/>
</div>
<div class="input-box app-public-url">
<label for="app-public-url">Public URL (useful if you have a reverse proxy)</label>
<input type="text" name="app-public-url" id="app-public-url" value="{{app-public-url}}" class="required" required/>
</div>
<!--
<div class="input-box app-admin-path">
<label for="app-admin-path">Admin Panel Path</label>
<input type="text" name="app-admin-path" id="app-admin-path" value="{{app-admin-path}}"/>
Expand All @@ -45,6 +50,7 @@ <h3 class="form-title">- App -</h3>
<label for="app-admin-hot-plug">Hot-Plug</label>
<input type="checkbox" value="1" name="app-admin-hot-plug" id="app-admin-hot-plug"{{&app-admin-hot-plug-checked}}/>
</div>
-->
<div class="input-box app-error">
<p class="installation-process-failed">There was an error during the installation process.</p>
</div>
Expand Down
2 changes: 1 addition & 1 deletion lib/actions/client/player-selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class PlayerSelector
div.classList.add('input-box');
let label = this.gameDom.createElement('label');
let classPathSelectId = 'class-path-select';
label.for = classPathSelectId;
label.htmlFor = classPathSelectId;
label.innerText = this.gameManager.services.translator.t(ActionsConst.SNIPPETS.SELECT_CLASS_PATH);
let select = this.gameDom.createElement('select');
select.id = classPathSelectId;
Expand Down
2 changes: 1 addition & 1 deletion lib/actions/client/preloader-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ class PreloaderHandler
if(sc.hasOwn(data.animationData, 'duration')){
animationCreateData.duration = data.animationData.duration;
} else {
animationCreateData.frameRate = sc.get(data.animationData, 'rate', uiScene.configuredFrameRate);
animationCreateData.frameRate = sc.get(data.animationData, 'frameRate', uiScene.configuredFrameRate);
}
if(sc.hasOwn(data.animationData, 'repeat')){
animationCreateData.repeat = data.animationData.repeat;
Expand Down
4 changes: 4 additions & 0 deletions lib/actions/client/receiver-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ class ReceiverWrapper extends Receiver

extractOwnerTargetAndType(currentScene, message)
{
if(!currentScene){
Logger.critical('Current scene not found.', currentScene, message);
return false;
}
let ownerSprite = false;
let targetSprite = false;
let targetType = ActionsConst.DATA_TYPE_VALUE_PLAYER;
Expand Down
4 changes: 4 additions & 0 deletions lib/actions/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ module.exports.ActionsConst = {
DATA_TYPE_VALUE_ENEMY: 'e',
DATA_TYPE_VALUE_PLAYER: 'p',
DATA_TYPE_VALUE_OBJECT: 'o',
EXTRA_DATA: {
KEY: 'sked',
SKILL_DELAY: 'sd'
},
DEFAULT_HIT_ANIMATION_KEY: 'default_hit',
ACTIONS: {
SUFFIX: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
*
* Reldens - ClassPathsImporter
* Reldens - ClassPathKeyFactory
*
*/

Expand Down
Loading

0 comments on commit 468257d

Please sign in to comment.