Skip to content
This repository has been archived by the owner on Sep 20, 2023. It is now read-only.

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Akida31 committed May 28, 2021
1 parent 9ad7c58 commit 80adda3
Show file tree
Hide file tree
Showing 10 changed files with 546 additions and 6 deletions.
76 changes: 70 additions & 6 deletions src/app/desktop/windows/terminal/terminal-states.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {of} from 'rxjs';
import {Device} from '../../../api/devices/device';
import {WindowDelegate} from '../../window/window-delegate';
import {File} from '../../../api/files/file';
import {Shell} from 'src/app/shell/shell';
import {ShellApi} from 'src/app/shell/shellapi';


function escapeHtml(html: string): string {
Expand All @@ -33,7 +35,7 @@ export abstract class CommandTerminalState implements TerminalState {
executeCommand(command: string, args: string[], io: IOHandler = null) {
const iohandler = io ? io : {
stdout: this.stdoutHandler.bind(this),
stdin: this.stdinHandler,
stdin: this.stdinHandler.bind(this),
stderr: this.stderrHandler.bind(this),
args: args
};
Expand Down Expand Up @@ -312,6 +314,10 @@ export class DefaultTerminalState extends CommandTerminalState {
executor: this.read.bind(this),
description: 'read input of user'
},
'msh': {
executor: this.msh.bind(this),
description: 'create a new shell'
},

// easter egg
'chaozz': {
Expand All @@ -325,8 +331,8 @@ export class DefaultTerminalState extends CommandTerminalState {
working_dir: string = Path.ROOT; // UUID of the working directory

constructor(protected websocket: WebsocketService, private settings: SettingsService, private fileService: FileService,
private domSanitizer: DomSanitizer, protected windowDelegate: WindowDelegate, protected activeDevice: Device,
protected terminal: TerminalAPI, public promptColor: string = null) {
private domSanitizer: DomSanitizer, protected windowDelegate: WindowDelegate, protected activeDevice: Device,
protected terminal: TerminalAPI, public promptColor: string = null) {
super();
}

Expand Down Expand Up @@ -439,6 +445,7 @@ export class DefaultTerminalState extends CommandTerminalState {
'device_uuid': this.activeDevice['uuid'],
}).subscribe((listData) => {
listData.services.forEach((service) => {
console.log(listData);
if (service.name === 'miner') {
miner = service;
this.websocket.ms('service', ['miner', 'wallet'], {
Expand Down Expand Up @@ -1947,6 +1954,10 @@ export class DefaultTerminalState extends CommandTerminalState {
this.setExitCode(0);
});
}

msh(_: IOHandler) {
this.terminal.pushState(new ShellTerminal(this.websocket, this.settings, this.fileService, this.domSanitizer, this.windowDelegate, this.activeDevice, this.terminal, this.promptColor));
}
}


Expand Down Expand Up @@ -2025,9 +2036,9 @@ export class BruteforceTerminalState extends ChoiceTerminalState {
};

constructor(terminal: TerminalAPI,
private domSanitizer: DomSanitizer,
private callback: (response: boolean) => void,
private startSeconds: number = 0) {
private domSanitizer: DomSanitizer,
private callback: (response: boolean) => void,
private startSeconds: number = 0) {
super(terminal);

this.intervalHandle = setInterval(() => {
Expand Down Expand Up @@ -2144,3 +2155,56 @@ enum OutputType {
TEXT,
NODE,
}

class ShellTerminal implements TerminalState {
private shell: Shell;

constructor(private websocket: WebsocketService, private settings: SettingsService, private fileService: FileService,
private domSanitizer: DomSanitizer, windowDelegate: WindowDelegate, private activeDevice: Device,
private terminal: TerminalAPI, private promptColor: string = null
) {
const shellApi = new ShellApi(this.websocket, this.settings, this.fileService, this.domSanitizer, windowDelegate, this.activeDevice, terminal, this.promptColor, this.refreshPrompt.bind(this))
this.shell = new Shell(
this.terminal.outputText.bind(this.terminal),
this.stdinHandler.bind(this),
this.terminal.outputText.bind(this.terminal),
shellApi,
);
}

/** default implementaion for stdin: reading from console */
stdinHandler(callback: (input: string) => void) {
return new DefaultStdin(this.terminal).read(callback);
}

execute(command: string) {
this.shell.execute(command);
}

autocomplete(content: string): string {
return this.shell.autocomplete(content);
}

getHistory(): string[] {
return this.shell.getHistory();
}

refreshPrompt() {
this.fileService.getAbsolutePath(this.activeDevice['uuid'], this.shell.working_dir).subscribe(path => {
//const color = this.domSanitizer.sanitize(SecurityContext.STYLE, this.promptColor || this.settings.getTPC());
// TODO undo this
const color = 'yellow';
const prompt = this.domSanitizer.bypassSecurityTrustHtml(
`<span style="color: ${color}">` +
`${escapeHtml(this.websocket.account.name)}@${escapeHtml(this.activeDevice['name'])}` +
`<span style="color: white">:</span>` +
`<span style="color: #0089ff;">/${path.join('/')}</span>$` +
`</span>`
);
this.terminal.changePrompt(prompt);
});

}

}

3 changes: 3 additions & 0 deletions src/app/shell/builtins/builtins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export {Status} from './status';
export {Hostname} from './hostname';
export {Miner} from './miner';
48 changes: 48 additions & 0 deletions src/app/shell/builtins/hostname.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {Command, IOHandler} from '../command';
import {Device} from '../../api/devices/device';
import {ShellApi} from '../shellapi';

export class Hostname extends Command {
constructor(shellApi: ShellApi) {
super('hostname', shellApi);
this.addDescription('changes the name of the device');
this.addPositionalArgument('name', true);
}

async run(iohandler: IOHandler): Promise<number> {
const args = iohandler.positionalArgs;
if (args.length === 1) {
const hostname = args[0];
let newDevice: Device;
try {
newDevice = await this.shellApi.websocket.ms('device', ['device', 'change_name'], {
device_uuid: this.shellApi.activeDevice['uuid'],
name: hostname
}).toPromise();
} catch {
iohandler.stderr('The hostname couldn\'t be changed');
return 1;
}
this.shellApi.activeDevice = newDevice;
this.shellApi.refreshPrompt();

if (this.shellApi.activeDevice.uuid === this.shellApi.windowDelegate.device.uuid) {
Object.assign(this.shellApi.windowDelegate.device, newDevice);
}
} else {
let device: Device;
try {
device = await this.shellApi.websocket.ms('device', ['device', 'info'], {device_uuid: this.shellApi.activeDevice['uuid']}).toPromise();
}
catch {
iohandler.stdout(this.shellApi.activeDevice['name']);
}
if (device['name'] !== this.shellApi.activeDevice['name']) {
this.shellApi.activeDevice = device;
this.shellApi.refreshPrompt();
}
iohandler.stdout(device['name']);
}
return 0;
}
}
142 changes: 142 additions & 0 deletions src/app/shell/builtins/miner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import {Command, IOHandler} from '../command';
import {ShellApi} from '../shellapi';

export class Miner extends Command {
constructor(shellApi: ShellApi) {
super('miner', shellApi);
this.addDescription('mangages morphcoin miners');
this.addSubcommand('look', MinerLook);
this.addSubcommand('wallet', MinerWallet);
this.addSubcommand('power', MinerPower);
this.addSubcommand('start', MinerStart);
}

async run(iohandler: IOHandler): Promise<number> {
this.showHelp(iohandler.stderr);
return -1;
}
}

async function getMinerService(shellApi: ShellApi): Promise<any> {
const listData = await shellApi.websocket.msPromise('service', ['list'], {
'device_uuid': shellApi.activeDevice['uuid'],
});
for (let i = 0; i < listData.services.length; i++) {
const miner: any = listData.services[i];
if (miner.name === 'miner') {
return miner;
}
}
throw new Error("miner service not found");
}

class MinerLook extends Command {
constructor(shellApi: ShellApi) {
super('look', shellApi);
this.addDescription('shows your current miner settings');
}

async run(iohandler: IOHandler): Promise<number> {
let miner: any;
try {
miner = await getMinerService(this.shellApi);
} catch {
iohandler.stderr('Miner service not reachable');
return 1;
}
const data = await this.shellApi.websocket.msPromise('service', ['miner', 'get'], {
'service_uuid': miner.uuid,
});
const wallet = data['wallet'];
const power = Math.round(data['power'] * 100);
iohandler.stdout('Wallet: ' + wallet);
iohandler.stdout('Mining Speed: ' + String(Number(miner.speed) * 60 * 60) + ' MC/h');
iohandler.stdout('Power: ' + power + '%');
return 0;
}
}

class MinerWallet extends Command {
constructor(shellApi: ShellApi) {
super('wallet', shellApi);
this.addDescription('set the miner to a wallet');
this.addPositionalArgument('wallet-id');
}

async run(iohandler: IOHandler): Promise<number> {
let miner: any;
try {
miner = await getMinerService(this.shellApi);
} catch {
iohandler.stderr('Miner service not reachable');
return 1;
}
try {
const newWallet = iohandler.positionalArgs[0];
await this.shellApi.websocket.msPromise('service', ['miner', 'wallet'], {
'service_uuid': miner.uuid,
'wallet_uuid': newWallet,
});
iohandler.stdout(`Set wallet to ${newWallet}`);
return 0;
} catch {
iohandler.stderr('Wallet is invalid.');
return 1;
}
}
}

class MinerPower extends Command {
constructor(shellApi: ShellApi) {
super('power', shellApi);
this.addDescription('set the power of your miner');
this.addPositionalArgument('<0-100>');
}

async run(iohandler: IOHandler): Promise<number> {
const args = iohandler.positionalArgs;
let miner: any;
try {
miner = await getMinerService(this.shellApi);
} catch {
iohandler.stderr('Miner service not reachable');
return 1;
}
if (args.length !== 1 || isNaN(Number(args[0])) || 0 > Number(args[0]) || Number(args[0]) > 100) {
this.showHelp(iohandler.stderr);
return 1;
}
await this.shellApi.websocket.msPromise('service', ['miner', 'power'], {
'service_uuid': miner.uuid,
'power': Number(args[1]) / 100,
});
iohandler.stdout(`Set Power to ${args[0]}`);
return 0;
}
}


class MinerStart extends Command {
constructor(shellApi: ShellApi) {
super('start', shellApi);
this.addDescription('start the miner');
this.addPositionalArgument('wallet-id');
}

async run(iohandler: IOHandler): Promise<number> {
const args = iohandler.positionalArgs;
try {
await this.shellApi.websocket.msPromise('service', ['create'], {
'device_uuid': this.shellApi.activeDevice['uuid'],
'name': 'miner',
'wallet_uuid': args[0],
});
return 0;
} catch {
iohandler.stderr('Invalid wallet');
return 1;
}
}
}


17 changes: 17 additions & 0 deletions src/app/shell/builtins/status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {Command, IOHandler} from '../command';
import {ShellApi} from '../shellapi';

export class Status extends Command {
constructor(shellApi: ShellApi) {
super('status', shellApi);
this.addDescription('displays the number of online players');
}

async run(iohandler: IOHandler): Promise<number> {
const r = await this.shellApi.websocket.requestPromise({
action: 'info'
});
iohandler.stdout('Online players: ' + r.online);
return 0;
}
}
13 changes: 13 additions & 0 deletions src/app/shell/builtins/template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {Command, IOHandler} from '../command';
import {ShellApi} from '../shellapi';

export class Template extends Command {
constructor(shellApi: ShellApi) {
super('COMMANDNAME', shellApi);
this.addDescription('');
}

async run(iohandler: IOHandler): Promise<number> {
return -1;
}
}
Loading

0 comments on commit 80adda3

Please sign in to comment.