summaryrefslogblamecommitdiff
path: root/src/main/manaplus/manaplus.ts
blob: 7573c845d3994776a476b2fb321798a919e2e9cb (plain) (tree)
1
2
3
4
5
6
7
8

                                                          
                         

                               
                                                       
                                                 
                                                   


                                 

                                                        










                                                                                




                                                                 







                                                              

 




                                         

                        
                                                                                                
                                                                                                                       

                     

                                                                                                        

             

                                 






                                                                                         


                                                                                                                  





                                      

                                              






                                 


                                                      
 




                                     
                                                                            
               
                                              





                                      
   
 

 

                                                                                        
                                                                







                                                                                                                
 


                                                                                                   
 



                                                                                              

                                                                                                             
                                                         





















                                                                                            
                                         
       
                              

                      
 


                               





                                                                                           

                                            
                                       





















                                                                                                        



















                                                                                                                                            

















































                                                                                                      
import { ManaPlusApp } from './manaApp/manaApp.interface';
import { ManaPlusAppWindows } from './manaApp/windows';
import * as os from 'os';
import * as path from 'path';
import * as fs from 'fs-extra';
import { app, ipcMain, shell, dialog } from 'electron';
import { Status, EventEmitter } from '../status';
import { ManaPlusAppLinux } from './manaApp/linux';

let ManaPlusInstance:ManaPlusApp;

let CurrentServer:{serverID:string,address:string}=null;

export namespace ManaPlus{

  export const ERRORS = {
    NOT_INITILIZED_YET_ERROR:new Error("The ManaPlus updater wasn't initilized")
  }

  export function init(){
    if(os.platform() == "win32"){
      ManaPlusInstance = new ManaPlusAppWindows();
      console.log("GameDir:"+ManaPlusInstance.getGameDir());
    }

    if(os.platform() == "linux"){
      ManaPlusInstance = new ManaPlusAppLinux();
      console.log("startCommand:"+ManaPlusInstance.startCommand);
    }
  }

  export async function update(){
    if(!wasInitilized())throw ERRORS.NOT_INITILIZED_YET_ERROR;

    return await ManaPlusInstance.update();
  }



  export async function start(args: any){
    CurrentServer={
      serverID:args.serverID,
      address:args.address
    };
    let params:string[];
    try {
      params = await makeParams(args.address,args.port,args.engine,args.username,args.password);
      //params = ['-v'];// DEBUG: This option is to disable manaplus for testing (open it just for getting the version)
    } catch (e){
      console.log(e);
      Status.showError("Launch Preperation Failed (LPF_PARMS)", e.message, "Launch preparation failed");
      Status.setPlaying(false);
      return;
    }
    let willUpdate:boolean=false;
    // check if it is installed
    if(ManaPlusInstance.isInstalled()){
      // Check if update is available and ask if the user wants to update
      try {
        let version = await ManaPlusInstance.updateAvailable();
        willUpdate = (version.isNewVersion && await updateDialog(version.newestVersion));
      } catch (e){
        console.log(e);
        Status.showError("Launch Preperation Failed (LPF_Update): This error can also mean that you are offline, \
please check you network connection first.", e.message, "Launch preparation failed")
        Status.setPlaying(false);
        return;
      }
    } else {
      // Not installed will install it
      willUpdate = true;
    }
    // Install/Update the gameclient if needed
    if(willUpdate){
      try {
        await update();
      } catch (error) {
        Status.setPlaying(false);
        throw error;
      }
      
    }

    //IDEA have client data updated here to, if needed


    // Run it
    Status.setGameRunning(true);
    EventEmitter.emit('closeWindow');
    EventEmitter.emit('openTray');
    await runManaProgram(params,ManaPlusInstance.startCommand,args.address);
    // On Close
    Status.setGameStatus({server: "Launcher"})
    Status.setGameRunning(false);
    Status.setPlaying(false);
    Status.removeActivity();
    EventEmitter.emit('reopenWindow');
    EventEmitter.emit('closeTray');
    CurrentServer=null;
  }

}

ipcMain.on('getScreenshots', (event:any, arg:string)=> {
  const screenshotsDir = path.normalize(app.getPath('userData')+`/screenshots/${arg}/`);
  fs.existsSync(screenshotsDir) || fs.mkdirSync(screenshotsDir);
    fs.readdir(screenshotsDir, (err, dir) => {
      let screenshots:string[]=[];
        for (var i = 0, path; path = dir[i]; i++) {
          screenshots.push(path);
        }
      event.sender.send('getScreenshots', {dir:screenshotsDir, screenshots:screenshots.reverse().slice(0, 24)});
    });
});

EventEmitter.on('Mana:openScreenshotDir', ()=>{
  shell.openItem(path.normalize(app.getPath('userData')+`/screenshots/${CurrentServer.address}/`));
});

function wasInitilized(){
  return typeof(ManaPlusInstance) !== "undefined" && typeof(ManaPlusInstance) !== "undefined";
}

async function makeParams(server: any,port: any,engine: any,username?: any,password?: any):Promise<string[]>{
    let parameters:string[] = [];
    if(server && engine && port && server != 'noServer'){
      parameters.push(...[
        "-s", server,
        "-y", engine,
        "-p", port
      ]);
      if(username && password){
        parameters.push(...[
          "-U", username,
          "-P", password
        ]);
      }
    }
    // Setup Paths and stuff
    const configDir = path.normalize(app.getPath('userData')+"/mana_config");
    const localDataDir = path.normalize(app.getPath('userData')+"/mana_local_data");
    const screenshotsDir = path.normalize(app.getPath('userData')+`/screenshots/${server}`);
    await fs.ensureDir(configDir);
    await fs.ensureDir(localDataDir);
    await fs.ensureDir(screenshotsDir);
    parameters.push(...[
      "-C", configDir,
      "-L", localDataDir,
      "--screenshot-dir", screenshotsDir,
    ]);
    //console.log(parameters);

    return parameters;
}

let manaplusInstance: any=null;

function runManaProgram(parameters: string[],gameExe:string,server?:string): Promise<any> {
  return new Promise(async(resolve, reject)=>{
    if(server){
      Status.setActivity(`Preparing Launch`);
      await setSkipUpdateWindows(server);
    }
    Status.setActivity(`Starting ManaPlus`);

    //console.log(gameExe, parameters);
    const child = require('child_process').execFile(gameExe, parameters, function(err:Error, data:any) {
         console.log(err);
         console.log(data.toString());
         Status.setActivity(`ManaPlus is running`);
    });
    child.on('close', ()=>{
      manaplusInstance = null;
      resolve();
    });
    child.on('error', ()=>{
      manaplusInstance = null;
      resolve();
      //// TODO: Handle Error
    });
    manaplusInstance = child;
  });
}

EventEmitter.on("Mana:killMana",()=>{
  if(manaplusInstance && manaplusInstance !== null)
    manaplusInstance.kill('SIGINT');
});

async function updateDialog(newestVersion:string):Promise<boolean>{
  const options = {
     type: 'info',
     title: `ManaPlus Update available: ${newestVersion}`,
     message: "Do you want to update now? Please note that you'll have to update eventually to ensure further compability with the servers",
     buttons: ['Nah, LATER', 'Update NOW']
   }
   let dialog = await dialogPromiseWrapper(options);
   console.log("....",dialog);
   return dialog === 1;
}

function dialogPromiseWrapper(options:any):Promise<number>{
  return new Promise((res, rej) => {
    dialog.showMessageBox(options, (index) => {
     res(index);
    })
  });
}

const default_server_config = '<?xml version="1.0"?>\
<configuration>\
 <option name="updateType" value="1"/>\
 <list name="player"/>\
</configuration>';
const parseString = require('xml2js').parseString, xml2js = require('xml2js');
async function setSkipUpdateWindows(server:string){
  const serverConfigXML = path.normalize(app.getPath('userData')+`/mana_config/${server}/config.xml`);

  if(fs.existsSync(serverConfigXML)){
    //add to this file
    try{
      let data = await fs.readFile(serverConfigXML, 'utf8');
      data = await editXML(data);
      await fs.outputFile(serverConfigXML, data);
    } catch (err){
      console.log(err);
    }

  }else{
    //create the file
    fs.outputFile(serverConfigXML, default_server_config);
  }

  return;
}

function editXML(xml:string):Promise<string>{
  return new Promise((res, rej)=>{
    parseString(xml, function(err:any, result:any){
        if(err) console.log(err);

        var json = result;
        const updaterVar = json.configuration.option.find((item:any)=>item.$.name=="updateType");
        if(updaterVar){
          if(updaterVar.$.value === 1){
            return rej(new Error("Has allready the right value"));
          }
          updaterVar.$.value = 1;
        }else{
          json.configuration.option.push({$:{name:"updateType",value:1}});
        }

        var builder = new xml2js.Builder();
        res(builder.buildObject(json));

    });
  });
}