-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from EvoEsports/dev
Version 0.7.0
- Loading branch information
Showing
92 changed files
with
4,700 additions
and
1,620 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
root: true | ||
env: | ||
- es2020: true | ||
extends: | ||
- "plugin:drizzle/recommended" | ||
parser: '@typescript-eslint/parser' | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,53 @@ | ||
# MINIcontrol | ||
A very simple plugin host for Trackmania United Forever, Maniaplanet and Trackmania 2020 games. | ||
<div align="center"> | ||
<img src="./images/minicontrol.png" width="60%" /> | ||
<br> | ||
<img alt="GitHub" src="https://img.shields.io/github/license/EvoEsports/minicontrol?label=License" /> | ||
<img alt="GitHub Tag" src="https://img.shields.io/github/v/tag/evoesports/minicontrol?label=Current%20Version" /> | ||
<img alt="NodeJS" src="https://img.shields.io/badge/node.js-6DA55F?logo=node.js&logoColor=white" /> | ||
<a href="https://discord.gg/evoesports"><img alt="Discord" src="https://img.shields.io/discord/384138149686935562?label=Discord&logo=discord&logoColor=fff"></a> | ||
</div> | ||
|
||
# QuickStart | ||
# Requirements | ||
|
||
1. `npm install` | ||
2. copy .env.example to .env and configure | ||
3. `npm start` | ||
- Node.js LTS installed | ||
- (optional) MySQL or PostgreSQL database | ||
- Windows, Linux or MacOS host | ||
|
||
# Quick Start | ||
|
||
### With Node.js | ||
1. Clone the repository or download the files from the `main` branch | ||
2. Run `npm install` | ||
3. Copy `.env.example` to `.env` and fill out all necessary information in the `.env` file. | ||
4. Run `npm start` | ||
|
||
### With Docker | ||
|
||
* See `docker/compose.yml` for an example Docker Compose file. | ||
|
||
See [documentation](./documentation/index.md) for more info! | ||
|
||
# Migrate from XAseco database | ||
# Migrating from XAseco? | ||
|
||
1. Export your old XAseco database with `mysqldump -u root -p databasename > xaseco.sql` | ||
2. Move `xaseco.sql` to the main folder of MINIcontrol | ||
3. Run in MINIControl folder: `tsx --env-file=.env xaseco.ts xaseco.sql` | ||
4. Start MINIcontrol | ||
|
||
# Migrating from PyPlanet? | ||
|
||
1. Export your old XAseco database with `mysqldump -u root -p databasename > pyplanet.sql` | ||
2. Move `xaseco.sql` to the main folder of MINIcontrol | ||
3. Run in MINIControl folder: `tsx --env-file=.env pyplanet.ts pyplanet.sql` | ||
4. Start MINIcontrol | ||
|
||
# Contributing | ||
See the documentation in `documentation/devs` to read more about the core concept of MINIcontrol and how plugins work. | ||
|
||
If you want to contribute changes or plugins to MINIcontrol, please open up an `Issue` first before you start working on things, so we can discuss the details of implementation, etc. | ||
|
||
1. run controller once to generate database structure | ||
2. `mysqldump -u root -p databasename > xaseco.sql` | ||
3. move `xaseco.sql` to `tools` | ||
5. run bun from Tools folder: `tsx xaseco.ts xaseco.sql` | ||
6. start controller | ||
We will not respond to random pull requests. | ||
|
||
### If you want to test your core changes in Docker: | ||
|
||
# Notes | ||
To build local docker image use: `docker build -t minicontrol:test -f docker/Dockerfile . ` | ||
* Build a local docker image: `docker build -t minicontrol:test -f docker/Dockerfile . ` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
interface Callable { | ||
(name: BillState): Promise<void>; | ||
} | ||
|
||
export class BillState { | ||
issuerLogin: string = ''; | ||
amount: number = 0; | ||
loginFrom: string = ''; | ||
/** If specified, sends the bill to the specified login, defaults to server login */ | ||
loginTo: string = ''; | ||
method: string = ''; | ||
message: string = ''; | ||
transactionId: number = -1; | ||
billId: number = -1; | ||
stateName: string = ''; | ||
|
||
onIssued?: Callable; | ||
onPayed?: Callable; | ||
onRefused?: Callable; | ||
onError?: Callable; | ||
|
||
async send() { | ||
switch (this.method) { | ||
case 'SendBill': { | ||
const billId = await tmc.server.call('SendBill', this.loginFrom, this.amount, this.message, this.loginTo); | ||
this.billId = billId; | ||
tmc.debug(`Bill ${billId} created.`); | ||
return; | ||
} | ||
case 'Pay': { | ||
const billId = await tmc.server.call('Pay', this.loginFrom, this.amount, this.message); | ||
this.billId = billId; | ||
tmc.debug(`Payment ${billId} created.`); | ||
return; | ||
} | ||
} | ||
} | ||
} | ||
|
||
export default class BillManager { | ||
billStates: BillState[] = []; | ||
|
||
/** @ignore */ | ||
afterInit() { | ||
if (tmc.game.Name == 'TmForever' || tmc.game.Name == 'ManiaPlanet') { | ||
tmc.server.addListener('Trackmania.BillUpdated', this.onBillUpdated, this); | ||
} | ||
} | ||
|
||
/** | ||
* Creates transaction | ||
* @returns {BillState} | ||
* @throws {Error} | ||
*/ | ||
createTransaction(type: 'SendBill' | 'Donate' | 'Pay', issuerLogin: string, loginFrom: string, amount: number, message: string): BillState { | ||
const state: BillState = new BillState(); | ||
state.issuerLogin = issuerLogin; | ||
state.loginFrom = loginFrom; | ||
state.loginTo = ''; | ||
state.message = message; | ||
state.amount = amount; | ||
state.method = type; | ||
state.billId = -1; | ||
state.transactionId = -1; | ||
state.stateName = ''; | ||
|
||
if (type == 'Pay') { | ||
if (!tmc.admins.includes(issuerLogin)) throw new Error('Not allowed.'); | ||
} | ||
if (type == 'SendBill') { | ||
if (!tmc.admins.includes(issuerLogin)) throw new Error('Not allowed.'); | ||
} | ||
if (type == 'Donate') { | ||
state.method = 'SendBill'; | ||
} | ||
if (amount < 10) { | ||
throw new Error('Minimum amount = 10'); | ||
} | ||
this.billStates.push(state); | ||
return state; | ||
} | ||
|
||
async getIngameCurrency() { | ||
switch (tmc.game.Name) { | ||
case 'ManiaPlanet': { | ||
return await tmc.server.call('GetServerPlanets'); | ||
} | ||
case 'TmForever': { | ||
return await tmc.server.call('GetServerCoppers'); | ||
} | ||
} | ||
} | ||
|
||
/** @ignore */ | ||
removeBill(billId:Number) { | ||
const index = this.billStates.findIndex((val) => val.billId == billId); | ||
if (index >= 0) { | ||
this.billStates.splice(index, 1); | ||
} else { | ||
tmc.cli("¤error¤Tried to remove a bill, but can't find it by index."); | ||
} | ||
} | ||
|
||
/** @ignore */ | ||
async onBillUpdated(data: any) { | ||
const BillId = data[0]; | ||
const State = data[1]; | ||
const StateName = data[2]; | ||
const TransactionId = data[3]; | ||
const bill = this.billStates.find((val) => (val.billId = BillId)); | ||
if (bill) { | ||
bill.stateName = StateName; | ||
if (TransactionId) bill.transactionId = TransactionId; | ||
tmc.debug(`Processing Bill ${BillId}: Status ¤white¤${StateName}¤info¤.`); | ||
switch (StateName) { | ||
case 'CreatingTransaction': { | ||
break; | ||
} | ||
case 'error': { | ||
if (bill.onError) { | ||
await bill.onError(bill); | ||
} | ||
this.removeBill(bill.billId); | ||
break; | ||
} | ||
case 'Issued': { | ||
if (bill.onIssued) { | ||
await bill.onIssued(bill); | ||
} | ||
break; | ||
} | ||
case 'Payed': { | ||
if (bill.onPayed) { | ||
await bill.onPayed(bill); | ||
} | ||
this.removeBill(bill.billId); | ||
break; | ||
} | ||
case 'Refused': { | ||
if (bill.onRefused) { | ||
await bill.onRefused(bill); | ||
} | ||
this.removeBill(bill.billId); | ||
break; | ||
} | ||
case 'ValidatingPayement': { | ||
break; | ||
} | ||
default: { | ||
if (State == 6) { | ||
if (bill.onError) { | ||
await bill.onError(bill); | ||
} | ||
this.removeBill(bill.billId); | ||
return; | ||
} | ||
|
||
tmc.cli(`Unknown Bill StateName: ¤white¤${StateName}`); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.