Compare commits
3 commits
8cf7cb66de
...
6307780b9c
| Author | SHA1 | Date | |
|---|---|---|---|
| 6307780b9c | |||
| d48f5a19a9 | |||
| 1b4e34a4ce |
47 changed files with 170897 additions and 316 deletions
|
|
@ -1,13 +0,0 @@
|
||||||
# Editor configuration, see https://editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
max_line_length = off
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
@ -1986,7 +1986,7 @@
|
||||||
<button class="close" data-bind="click: cancelDeparseEdit">×</button>
|
<button class="close" data-bind="click: cancelDeparseEdit">×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>JSON! Its all JSON. Only magical ones are the 'BlueprintGeneratedClass' and 'SoundWave' items - these
|
<p>JSON! Its all JSON. Only magical ones are the 'BlueprintGeneratedClassModel' and 'SoundWave' items - these
|
||||||
appear as an array of two items, the 'class' name and the argument for them.</p>
|
appear as an array of two items, the 'class' name and the argument for them.</p>
|
||||||
<div id="deparse-editor"></div>
|
<div id="deparse-editor"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,22 @@ import { NgModule } from '@angular/core';
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
import { RawEditorComponent } from "./pages/raw-editor/raw-editor.component";
|
import { RawEditorComponent } from "./pages/raw-editor/raw-editor.component";
|
||||||
import { ConfigComponent } from "./pages/config/config.component";
|
import { ConfigComponent } from "./pages/config/config.component";
|
||||||
|
import { QuestsComponent } from "./pages/config/quests/quests.component";
|
||||||
|
import { GridComponent } from "./pages/config/grid/grid.component";
|
||||||
|
import { DbsComponent } from "./pages/config/dbs/dbs.component";
|
||||||
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{path: 'raw', component: RawEditorComponent},
|
{path: 'raw', component: RawEditorComponent},
|
||||||
{path: 'config', component: ConfigComponent}
|
{
|
||||||
|
path: 'config', component: ConfigComponent,
|
||||||
|
children: [
|
||||||
|
{path: '', redirectTo: 'grid', pathMatch: 'full'},
|
||||||
|
{path: 'grid', component: GridComponent},
|
||||||
|
{path: 'dbs', component: DbsComponent},
|
||||||
|
{path: 'quests', component: QuestsComponent},
|
||||||
|
]
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import { TestBed, async } from '@angular/core/testing';
|
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
|
|
||||||
describe('AppComponent', () => {
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
RouterTestingModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
AppComponent
|
|
||||||
],
|
|
||||||
}).compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should create the app', () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.debugElement.componentInstance;
|
|
||||||
expect(app).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should have as title 'atlas-config-generator'`, () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.debugElement.componentInstance;
|
|
||||||
expect(app.title).toEqual('atlas-config-generator');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render title', () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
fixture.detectChanges();
|
|
||||||
const compiled = fixture.debugElement.nativeElement;
|
|
||||||
expect(compiled.querySelector('.content span').textContent).toContain('atlas-config-generator app is running!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import { Server } from "./server";
|
||||||
|
import { ServerGridModel } from "./models/serverGrid.model";
|
||||||
|
import * as data from '../serverGridExample.json';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
|
|
@ -7,4 +10,10 @@ import { Component } from '@angular/core';
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'atlas-config-generator';
|
title = 'atlas-config-generator';
|
||||||
|
|
||||||
|
constructor(private server: Server) {
|
||||||
|
// Temporary just load all the grid. Remove later.
|
||||||
|
this.server.serverGrid = new ServerGridModel().deserialize((data as any).default);
|
||||||
|
console.log(this.server.serverGrid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,27 @@ import { ConfigComponent } from './pages/config/config.component';
|
||||||
import { FormsModule } from "@angular/forms";
|
import { FormsModule } from "@angular/forms";
|
||||||
import { Server } from "./server";
|
import { Server } from "./server";
|
||||||
import { PegjsService } from "./services/pegjs.service";
|
import { PegjsService } from "./services/pegjs.service";
|
||||||
|
import { QuestsComponent } from './pages/config/quests/quests.component';
|
||||||
|
import { GridComponent } from './pages/config/grid/grid.component';
|
||||||
|
import { NumberComponent } from './components/form/number/number.component';
|
||||||
|
import { TextComponent } from './components/form/text/text.component';
|
||||||
|
import { PasswordComponent } from './components/form/password/password.component';
|
||||||
|
import { DbsComponent } from './pages/config/dbs/dbs.component';
|
||||||
|
import { CheckboxComponent } from './components/form/checkbox/checkbox.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
RawEditorComponent,
|
RawEditorComponent,
|
||||||
CodeEditorComponent,
|
CodeEditorComponent,
|
||||||
ConfigComponent
|
ConfigComponent,
|
||||||
|
QuestsComponent,
|
||||||
|
GridComponent,
|
||||||
|
NumberComponent,
|
||||||
|
TextComponent,
|
||||||
|
PasswordComponent,
|
||||||
|
DbsComponent,
|
||||||
|
CheckboxComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
|
|
||||||
7
src/app/components/form/checkbox/checkbox.component.html
Normal file
7
src/app/components/form/checkbox/checkbox.component.html
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="check-{{ id }}" class="col-2">{{ label }}</label>
|
||||||
|
<div class="col-10">
|
||||||
|
<input id="check-{{ id }}" type="checkbox" class="form-control" (ngModelChange)="checkboxChange.emit($event)" [ngModel]="checkbox">
|
||||||
|
<small class="form-text text-muted" *ngIf="help">{{ help }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
19
src/app/components/form/checkbox/checkbox.component.ts
Normal file
19
src/app/components/form/checkbox/checkbox.component.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-checkbox',
|
||||||
|
templateUrl: './checkbox.component.html'
|
||||||
|
})
|
||||||
|
export class CheckboxComponent implements OnInit {
|
||||||
|
@Input() checkbox: boolean;
|
||||||
|
@Output() checkboxChange = new EventEmitter();
|
||||||
|
@Input() label: string;
|
||||||
|
@Input() id: string;
|
||||||
|
@Input() help: string;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
7
src/app/components/form/number/number.component.html
Normal file
7
src/app/components/form/number/number.component.html
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="num-{{ id }}" class="col-2">{{ label }}</label>
|
||||||
|
<div class="col-10">
|
||||||
|
<input id="num-{{ id }}" type="number" class="form-control" (ngModelChange)="numberChange.emit($event)" [ngModel]="number">
|
||||||
|
<small class="form-text text-muted" *ngIf="help">{{ help }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
19
src/app/components/form/number/number.component.ts
Normal file
19
src/app/components/form/number/number.component.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-number',
|
||||||
|
templateUrl: './number.component.html'
|
||||||
|
})
|
||||||
|
export class NumberComponent implements OnInit {
|
||||||
|
@Input() number: number;
|
||||||
|
@Output() numberChange = new EventEmitter();
|
||||||
|
@Input() label: string;
|
||||||
|
@Input() id: string;
|
||||||
|
@Input() help: string;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
13
src/app/components/form/password/password.component.html
Normal file
13
src/app/components/form/password/password.component.html
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="text-{{ id }}" class="col-2">{{ label }}</label>
|
||||||
|
<div class="col-10">
|
||||||
|
<div class="input-group">
|
||||||
|
<input id="text-{{ id }}" type="{{ show ? 'text' : 'password' }}" class="form-control"
|
||||||
|
(ngModelChange)="passwordChange.emit($event)" [ngModel]="password">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-warning" (click)="toggleShow()">{{ show ? 'Hide' : 'Show' }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<small class="form-text text-muted" *ngIf="help">{{ help }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
23
src/app/components/form/password/password.component.ts
Normal file
23
src/app/components/form/password/password.component.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-password',
|
||||||
|
templateUrl: './password.component.html'
|
||||||
|
})
|
||||||
|
export class PasswordComponent implements OnInit {
|
||||||
|
@Input() password: string;
|
||||||
|
@Output() passwordChange = new EventEmitter();
|
||||||
|
@Input() label: string;
|
||||||
|
@Input() id: string;
|
||||||
|
@Input() help: string;
|
||||||
|
private show: boolean = false;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
private toggleShow() {
|
||||||
|
this.show = !this.show;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/app/components/form/text/text.component.html
Normal file
12
src/app/components/form/text/text.component.html
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="text-{{ id }}" class="col-2">{{ label }}</label>
|
||||||
|
<div class="col-10">
|
||||||
|
<div class="input-group">
|
||||||
|
<input id="text-{{ id }}" type="text" class="form-control" (ngModelChange)="textChange.emit($event)" [ngModel]="text">
|
||||||
|
<div class="input-group-append" *ngIf="postButtonText">
|
||||||
|
<button class="btn btn-outline-primary" (click)="postButton.emit($event)">{{ postButtonText || "click me" }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<small class="form-text text-muted" *ngIf="help">{{ help }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
20
src/app/components/form/text/text.component.ts
Normal file
20
src/app/components/form/text/text.component.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-text',
|
||||||
|
templateUrl: './text.component.html'
|
||||||
|
})
|
||||||
|
export class TextComponent implements OnInit {
|
||||||
|
@Input() text: string;
|
||||||
|
@Output() textChange = new EventEmitter();
|
||||||
|
@Input() postButtonText: string;
|
||||||
|
@Output() postButton = new EventEmitter();
|
||||||
|
@Input() label: string;
|
||||||
|
@Input() id: string;
|
||||||
|
@Input() help: string;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/app/models/atlasData/blueprintGeneratedClass.model.ts
Normal file
15
src/app/models/atlasData/blueprintGeneratedClass.model.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import {Deserialize} from "../util/deserialize.model";
|
||||||
|
|
||||||
|
export class BlueprintGeneratedClassModel implements Deserialize {
|
||||||
|
public blueprint: string;
|
||||||
|
|
||||||
|
public deserialize(raw: any): this {
|
||||||
|
if( raw[0] !== 'BlueprintGeneratedClass') Error('wrong type, expecting BlueprintGeneratedClassModel, got [' + raw[0] + ']!');
|
||||||
|
this.blueprint = raw[1];
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
public toJSON(): object {
|
||||||
|
return [ 'BlueprintGeneratedClass', this.blueprint ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
import { ToJSON } from "../util/toJson";
|
|
||||||
|
|
||||||
export class BlueprintGeneratedClass implements ToJSON {
|
|
||||||
public texture: string;
|
|
||||||
|
|
||||||
constructor(raw: object) {
|
|
||||||
if( raw[0] !== 'BlueprintGeneratedClass') Error('wrong type, expecting BlueprintGeneratedClass, got [' + raw[0] + ']!');
|
|
||||||
this.texture = raw[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
public toJSON(): object {
|
|
||||||
return [ 'BlueprintGeneratedClass', this.texture ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
37
src/app/models/atlasData/questEntry.model.ts
Normal file
37
src/app/models/atlasData/questEntry.model.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { Texture2DModel } from "./texture2D.model";
|
||||||
|
import { Deserialize } from "../util/deserialize.model";
|
||||||
|
import { BlueprintGeneratedClassModel } from "./blueprintGeneratedClass.model";
|
||||||
|
import { QuestPointsOfInterestModel } from "./questPointsOfInterest.model";
|
||||||
|
|
||||||
|
export class QuestEntryModel implements Deserialize {
|
||||||
|
public QuestID: number;
|
||||||
|
public CompletedIcon: Texture2DModel;
|
||||||
|
public UncompletedIcon: Texture2DModel;
|
||||||
|
public QuestName: string;
|
||||||
|
public QuestDescription: string;
|
||||||
|
public UnlockFeatNames: string[];
|
||||||
|
public CompleteGiveEngramClasses: Array<BlueprintGeneratedClassModel>;
|
||||||
|
public QuestPointsOfInterest: Array<QuestPointsOfInterestModel>;
|
||||||
|
|
||||||
|
public deserialize(raw: any): this {
|
||||||
|
Object.assign(this, raw);
|
||||||
|
this.CompletedIcon = new Texture2DModel().deserialize(raw.CompletedIcon);
|
||||||
|
this.UncompletedIcon = new Texture2DModel().deserialize(raw.UncompletedIcon);
|
||||||
|
// Some Quests dont have an engram on completion
|
||||||
|
if (this.CompleteGiveEngramClasses !== undefined)
|
||||||
|
this.CompleteGiveEngramClasses
|
||||||
|
= this.CompleteGiveEngramClasses.map(i => new BlueprintGeneratedClassModel().deserialize(i));
|
||||||
|
// Some Quests have no points of interest to complete
|
||||||
|
if (this.QuestPointsOfInterest !== undefined)
|
||||||
|
this.QuestPointsOfInterest
|
||||||
|
= this.QuestPointsOfInterest.map(i => new QuestPointsOfInterestModel().deserialize(i));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toJSON() {
|
||||||
|
let json = Object.assign({}, this);
|
||||||
|
if (this.CompleteGiveEngramClasses === undefined) delete json.CompleteGiveEngramClasses;
|
||||||
|
if (this.QuestPointsOfInterest === undefined) delete json.QuestPointsOfInterest;
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
import { Texture2D } from "./texture2D";
|
|
||||||
|
|
||||||
export class QuestEntry {
|
|
||||||
public QuestID: number;
|
|
||||||
public CompletedIcon: Texture2D;
|
|
||||||
public UncompletedIcon: Texture2D;
|
|
||||||
public QuestName: string;
|
|
||||||
public QuestDescription: string;
|
|
||||||
public UnlockFeatNames: Array<string>;
|
|
||||||
public CompleteGiveEngramClasses: object;
|
|
||||||
public QuestPointsOfInterest: Array<object>;
|
|
||||||
|
|
||||||
constructor(raw?: Partial<QuestEntry>) {
|
|
||||||
Object.assign(this, raw);
|
|
||||||
this.CompletedIcon = new Texture2D(raw.CompletedIcon);
|
|
||||||
this.UncompletedIcon = new Texture2D(raw.UncompletedIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public toJSON() {
|
|
||||||
let output = {};
|
|
||||||
|
|
||||||
const JsonSubModels = [
|
|
||||||
'CompletedIcon',
|
|
||||||
'UncompletedIcon'
|
|
||||||
];
|
|
||||||
|
|
||||||
JsonSubModels.forEach(item => {
|
|
||||||
output[item] = this[item].toJSON();
|
|
||||||
});
|
|
||||||
|
|
||||||
const RawSubData = [
|
|
||||||
'QuestID',
|
|
||||||
'QuestName',
|
|
||||||
'QuestDescription',
|
|
||||||
'UnlockFeatNames',
|
|
||||||
'CompleteGiveEngramClasses',
|
|
||||||
'QuestPointsOfInterest'
|
|
||||||
];
|
|
||||||
|
|
||||||
RawSubData.forEach(item => {
|
|
||||||
output[item] = this[item];
|
|
||||||
});
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
20
src/app/models/atlasData/questPointsOfInterest.model.ts
Normal file
20
src/app/models/atlasData/questPointsOfInterest.model.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { Deserialize } from "../util/deserialize.model";
|
||||||
|
import { WorldMapPositionModel } from "./worldMapPosition.model";
|
||||||
|
import { Texture2DModel } from "./texture2D.model";
|
||||||
|
|
||||||
|
export class QuestPointsOfInterestModel implements Deserialize {
|
||||||
|
public PointOfInterestID: number;
|
||||||
|
public PointOfInterestName: string;
|
||||||
|
public UnlockFeatNames: Array<string>;
|
||||||
|
public WorldMapPosition: WorldMapPositionModel;
|
||||||
|
public CompletedIcon: Texture2DModel;
|
||||||
|
public UncompletedIcon: Texture2DModel;
|
||||||
|
|
||||||
|
public deserialize(input: any): this {
|
||||||
|
Object.assign(this, input);
|
||||||
|
this.WorldMapPosition = new WorldMapPositionModel().deserialize(input.WorldMapPosition);
|
||||||
|
this.CompletedIcon = new Texture2DModel().deserialize(input.CompletedIcon);
|
||||||
|
this.UncompletedIcon = new Texture2DModel().deserialize(input.UncompletedIcon);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/app/models/atlasData/server.model.ts
Normal file
51
src/app/models/atlasData/server.model.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { Deserialize } from "../util/deserialize.model";
|
||||||
|
import { ServerSublevelModel } from "./serverSublevel.model";
|
||||||
|
|
||||||
|
export class ServerModel implements Deserialize {
|
||||||
|
gridX: number;
|
||||||
|
gridY: number;
|
||||||
|
MachineIdTag: string;
|
||||||
|
ip: string;
|
||||||
|
name: string;
|
||||||
|
port: number;
|
||||||
|
gamePort: number;
|
||||||
|
seamlessDataPort: number;
|
||||||
|
isHomeServer: boolean;
|
||||||
|
AdditionalCmdLineParams: string;
|
||||||
|
OverrideShooterGameModeDefaultGameIni: object;
|
||||||
|
floorZDist: number;
|
||||||
|
utcOffset: number;
|
||||||
|
transitionMinZ: number;
|
||||||
|
GlobalBiomeSeamlessServerGridPreOffsetValues: string;
|
||||||
|
GlobalBiomeSeamlessServerGridPreOffsetValuesOceanWater: string;
|
||||||
|
OceanDinoDepthEntriesOverride: string;
|
||||||
|
oceanFloatsamCratesOverride: string;
|
||||||
|
treasureMapLootTablesOverride: string;
|
||||||
|
oceanEpicSpawnEntriesOverrideTemplateName: string;
|
||||||
|
NPCShipSpawnEntriesOverrideTemplateName: string;
|
||||||
|
regionOverrides: string;
|
||||||
|
waterColorR: number;
|
||||||
|
waterColorG: number;
|
||||||
|
waterColorB: number;
|
||||||
|
skyStyleIndex: number;
|
||||||
|
serverIslandPointsMultiplier: number;
|
||||||
|
lastModified: string;
|
||||||
|
lastImageOverride: string;
|
||||||
|
islandLocked: boolean;
|
||||||
|
discoLocked: boolean;
|
||||||
|
pathsLocked: boolean;
|
||||||
|
extraSublevels: string[];
|
||||||
|
totalExtraSublevels: string[];
|
||||||
|
islandInstances;
|
||||||
|
discoZones;
|
||||||
|
spawnRegions;
|
||||||
|
serverTemplateName: string;
|
||||||
|
|
||||||
|
sublevels: ServerSublevelModel[];
|
||||||
|
|
||||||
|
deserialize(input: any): this {
|
||||||
|
Object.assign(this, input);
|
||||||
|
this.sublevels = this.sublevels.map(i => new ServerSublevelModel().deserialize(i));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/app/models/atlasData/serverSublevel.model.ts
Normal file
17
src/app/models/atlasData/serverSublevel.model.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Deserialize } from "../util/deserialize.model";
|
||||||
|
|
||||||
|
export class ServerSublevelModel implements Deserialize {
|
||||||
|
public name: string;
|
||||||
|
public additionalTranslationX: number;
|
||||||
|
public additionalTranslationY: number;
|
||||||
|
public additionalTranslationZ: number;
|
||||||
|
public additionalRotationPitch: number;
|
||||||
|
public additionalRotationYaw: number;
|
||||||
|
public additionalRotationRoll: number;
|
||||||
|
public id: number;
|
||||||
|
public landscapeMaterialOverride: number;
|
||||||
|
|
||||||
|
deserialize(input: any): this {
|
||||||
|
return Object.assign(this, input);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/app/models/atlasData/texture2D.model.ts
Normal file
15
src/app/models/atlasData/texture2D.model.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Deserialize } from "../util/deserialize.model";
|
||||||
|
|
||||||
|
export class Texture2DModel implements Deserialize {
|
||||||
|
public texture: string;
|
||||||
|
|
||||||
|
public deserialize(raw: any): this {
|
||||||
|
if (raw[0] !== 'Texture2D') Error('wrong type, expecting Texture2DModel, got [' + raw[0] + ']!');
|
||||||
|
this.texture = raw[1];
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
public toJSON(): object {
|
||||||
|
return ['Texture2D', this.texture];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
import { ToJSON } from "../util/toJson";
|
|
||||||
|
|
||||||
export class Texture2D implements ToJSON {
|
|
||||||
public texture: string;
|
|
||||||
|
|
||||||
constructor(raw: object) {
|
|
||||||
if( raw[0] !== 'Texture2D') Error('wrong type, expecting Texture2D, got [' + raw[0] + ']!');
|
|
||||||
this.texture = raw[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
public toJSON(): object {
|
|
||||||
return [ 'Texture2D', this.texture ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
src/app/models/atlasData/worldMapPosition.model.ts
Normal file
11
src/app/models/atlasData/worldMapPosition.model.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Deserialize } from "../util/deserialize.model";
|
||||||
|
|
||||||
|
export class WorldMapPositionModel implements Deserialize {
|
||||||
|
public X: number;
|
||||||
|
public Y: number;
|
||||||
|
|
||||||
|
public deserialize(input: any): this {
|
||||||
|
Object.assign(this, input);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import {DeserializeJson} from "./util/deserializeJson.model";
|
import {Deserialize} from "./util/deserialize.model";
|
||||||
|
|
||||||
export class DatabaseModel implements DeserializeJson {
|
export class DatabaseConnectionModel implements Deserialize {
|
||||||
public Name: string;
|
public Name: string;
|
||||||
public URL: string;
|
public URL: string;
|
||||||
public Port: number;
|
public Port: number;
|
||||||
|
|
@ -1,25 +1,18 @@
|
||||||
import { PegjsService } from "../services/pegjs.service";
|
import { PegjsService } from "../services/pegjs.service";
|
||||||
import { ToAtlas } from "./util/toAtlas";
|
import { QuestEntryModel } from "./atlasData/questEntry.model";
|
||||||
import { QuestEntry } from "./atlasData/questEntry";
|
import { Deserialize } from "./util/deserialize.model";
|
||||||
|
|
||||||
export class GlobalGameplaySetupModel implements ToAtlas {
|
export class GlobalGameplaySetupModel implements Deserialize {
|
||||||
public QuestEntries: Array<QuestEntry> = [];
|
QuestEntries: QuestEntryModel[];
|
||||||
|
|
||||||
constructor(raw: any = "()") {
|
public deserialize(raw: string): this {
|
||||||
const rawData = <object>PegjsService.parse(raw);
|
const rawData = PegjsService.parse(raw);
|
||||||
Object.assign(this, rawData);
|
Object.assign(this, rawData);
|
||||||
let tempQuestEntries = [];
|
this.QuestEntries = this.QuestEntries.map(i => new QuestEntryModel().deserialize(i));
|
||||||
this.QuestEntries.forEach(item => {
|
return this;
|
||||||
tempQuestEntries.push(new QuestEntry(item));
|
|
||||||
});
|
|
||||||
this.QuestEntries = tempQuestEntries;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public toAtlas(): string {
|
public toJSON(): string {
|
||||||
const output = [];
|
return PegjsService.format(this, true);
|
||||||
this.QuestEntries.forEach(item => {
|
|
||||||
output.push(item.toJSON());
|
|
||||||
});
|
|
||||||
return PegjsService.format({QuestEntries: output});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
import { TribeLogConfigModel } from "./tribeLogConfig.model";
|
import { TribeLogConfigModel } from "./tribeLogConfig.model";
|
||||||
import { SharedLogConfigModel } from "./sharedLogConfig.model";
|
import { SharedLogConfigModel } from "./sharedLogConfig.model";
|
||||||
import { TravelDataConfigModel } from "./travelDataConfig.model";
|
import { TravelDataConfigModel } from "./travelDataConfig.model";
|
||||||
import { ToJSON } from "./util/toJson";
|
|
||||||
import { GlobalGameplaySetupModel } from "./GlobalGameplaySetupModel";
|
import { GlobalGameplaySetupModel } from "./GlobalGameplaySetupModel";
|
||||||
|
import { Deserialize } from "./util/deserialize.model";
|
||||||
|
import { DatabaseConnectionModel } from "./databaseConnection.model";
|
||||||
|
import { ServerModel } from "./atlasData/server.model";
|
||||||
|
|
||||||
export class ServerGridModel implements ToJSON {
|
export class ServerGridModel implements Deserialize {
|
||||||
// Server Argument Section
|
// Server Argument Section
|
||||||
public BaseServerArgs: string = "";
|
// Used internally by Grapeshot
|
||||||
public AdditionalCmdLineParams: string = "";
|
//public BaseServerArgs: string = "";
|
||||||
|
// Probably also internal to Grapeshot
|
||||||
|
//public AdditionalCmdLineParams: string = "";
|
||||||
|
|
||||||
// World Options
|
// World Options
|
||||||
public WorldFriendlyName: string = "New Server";
|
public WorldFriendlyName: string = "New Server";
|
||||||
|
|
@ -19,12 +23,17 @@ export class ServerGridModel implements ToJSON {
|
||||||
public gridSize: number = 1000;
|
public gridSize: number = 1000;
|
||||||
public totalGridsX: number = 1;
|
public totalGridsX: number = 1;
|
||||||
public totalGridsY: number = 1;
|
public totalGridsY: number = 1;
|
||||||
public coordsScaling: number = 0.000000000001;
|
|
||||||
public globalTransitionMinZ: number = 0.0;
|
public globalTransitionMinZ: number = 0.0;
|
||||||
|
|
||||||
|
// Used by ServerGridEditor for Zoom Level, so ignored
|
||||||
|
// Will be added if present in config when loading.
|
||||||
|
//public coordsScaling: number = 0.000000000001;
|
||||||
|
|
||||||
// Image Paths
|
// Image Paths
|
||||||
public backgroundImgPath: string = "image.png";
|
// Used for generating tile output
|
||||||
public discoZonesImagePath: string = "image.png";
|
//public backgroundImgPath: string = "image.png";
|
||||||
|
// Used for displaying discovery zones in ServerGridEditor
|
||||||
|
//public discoZonesImagePath: string = "image.png";
|
||||||
|
|
||||||
// URL Options
|
// URL Options
|
||||||
public MetaWorldURL: string = "";
|
public MetaWorldURL: string = "";
|
||||||
|
|
@ -37,13 +46,13 @@ export class ServerGridModel implements ToJSON {
|
||||||
public columnUTCOffset: number = 0.0;
|
public columnUTCOffset: number = 0.0;
|
||||||
public lastImageOverride: string = "0001-01-01T00:00:00";
|
public lastImageOverride: string = "0001-01-01T00:00:00";
|
||||||
|
|
||||||
// Info Options
|
// Info Options for ServerGridEditor
|
||||||
public showServerInfo: boolean = false;
|
// public showServerInfo: boolean = false;
|
||||||
public showDiscoZoneInfo: boolean = false;
|
// public showDiscoZoneInfo: boolean = false;
|
||||||
public showShipPathsInfo: boolean = false;
|
// public showShipPathsInfo: boolean = false;
|
||||||
public showIslandNames: boolean = false;
|
// public showIslandNames: boolean = false;
|
||||||
public showLines: boolean = false;
|
// public showLines: boolean = false;
|
||||||
public showBackground: boolean = false;
|
// public showBackground: boolean = false;
|
||||||
|
|
||||||
// S3 Options
|
// S3 Options
|
||||||
public LocalS3URL: string = "";
|
public LocalS3URL: string = "";
|
||||||
|
|
@ -52,9 +61,12 @@ export class ServerGridModel implements ToJSON {
|
||||||
public LocalS3BucketName: string = "";
|
public LocalS3BucketName: string = "";
|
||||||
public LocalS3Region: string = "";
|
public LocalS3Region: string = "";
|
||||||
|
|
||||||
// Unsorted...
|
// ID Generator current values
|
||||||
public shipPathsIdGenerator: number = 1;
|
// Used for individual ship path
|
||||||
public idGenerator: number = 127;
|
public shipPathsIdGenerator: number = 0;
|
||||||
|
// Used for Discovery Zone IDs
|
||||||
|
public idGenerator: number = 0;
|
||||||
|
// Unused as far as can see in ServerGridEditor
|
||||||
public regionsIdGenerator: number = 0;
|
public regionsIdGenerator: number = 0;
|
||||||
|
|
||||||
// Log Configs
|
// Log Configs
|
||||||
|
|
@ -62,97 +74,20 @@ export class ServerGridModel implements ToJSON {
|
||||||
public SharedLogConfig: SharedLogConfigModel = new SharedLogConfigModel();
|
public SharedLogConfig: SharedLogConfigModel = new SharedLogConfigModel();
|
||||||
public TravelDataConfig: TravelDataConfigModel = new TravelDataConfigModel();
|
public TravelDataConfig: TravelDataConfigModel = new TravelDataConfigModel();
|
||||||
|
|
||||||
// Large Objects of Doom
|
// Quest Config
|
||||||
public globalGameplaySetup: GlobalGameplaySetupModel = new GlobalGameplaySetupModel();
|
public globalGameplaySetup: GlobalGameplaySetupModel = new GlobalGameplaySetupModel();
|
||||||
|
|
||||||
constructor(raw?: Partial<ServerGridModel>) {
|
public DatabaseConnections: DatabaseConnectionModel[];
|
||||||
Object.assign(this, raw);
|
servers: ServerModel[];
|
||||||
this.SharedLogConfig = new SharedLogConfigModel(raw.SharedLogConfig);
|
|
||||||
this.TribeLogConfig = new TribeLogConfigModel(raw.TribeLogConfig);
|
|
||||||
this.TravelDataConfig = new TravelDataConfigModel(raw.TravelDataConfig);
|
|
||||||
this.globalGameplaySetup = new GlobalGameplaySetupModel(raw.globalGameplaySetup);
|
|
||||||
console.log(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public toJSON() {
|
public deserialize(input: any): this {
|
||||||
let output = {};
|
Object.assign(this, input);
|
||||||
|
this.SharedLogConfig = new SharedLogConfigModel().deserialize(input.SharedLogConfig);
|
||||||
// All full models of this object for deflation
|
this.TribeLogConfig = new TribeLogConfigModel().deserialize(input.TribeLogConfig);
|
||||||
const JsonSubModels = [
|
this.TravelDataConfig = new TravelDataConfigModel().deserialize(input.TravelDataConfig);
|
||||||
'SharedLogConfig',
|
this.globalGameplaySetup = new GlobalGameplaySetupModel().deserialize(input.globalGameplaySetup);
|
||||||
'TribeLogConfig',
|
this.DatabaseConnections = this.DatabaseConnections.map(i => new DatabaseConnectionModel().deserialize(i));
|
||||||
'TravelDataConfig',
|
this.servers = this.servers.map(i => new ServerModel().deserialize(i));
|
||||||
];
|
return this;
|
||||||
|
|
||||||
JsonSubModels.forEach(item => {
|
|
||||||
output[item] = this[item].toJSON();
|
|
||||||
});
|
|
||||||
|
|
||||||
const AtlasSubModels = [
|
|
||||||
'globalGameplaySetup'
|
|
||||||
];
|
|
||||||
|
|
||||||
AtlasSubModels.forEach(item => {
|
|
||||||
output[item] = this[item].toAtlas();
|
|
||||||
});
|
|
||||||
|
|
||||||
const RawSubData = [
|
|
||||||
'BaseServerArgs',
|
|
||||||
'AdditionalCmdLineParams',
|
|
||||||
|
|
||||||
// World Options
|
|
||||||
'WorldFriendlyName',
|
|
||||||
'WorldAtlasId',
|
|
||||||
'WorldAtlasPassword',
|
|
||||||
'ModIDs',
|
|
||||||
|
|
||||||
// Grid Options
|
|
||||||
'gridSize',
|
|
||||||
'totalGridsX',
|
|
||||||
'totalGridsY',
|
|
||||||
'coordsScaling',
|
|
||||||
'globalTransitionMinZ',
|
|
||||||
|
|
||||||
// Image Paths
|
|
||||||
'backgroundImgPath',
|
|
||||||
'discoZonesImagePath',
|
|
||||||
|
|
||||||
// URL Options
|
|
||||||
'MetaWorldURL',
|
|
||||||
'AuthListURL',
|
|
||||||
'MapImageURL',
|
|
||||||
|
|
||||||
// Time Options
|
|
||||||
'Day0',
|
|
||||||
'bUseUTCTime',
|
|
||||||
'columnUTCOffset',
|
|
||||||
'lastImageOverride',
|
|
||||||
|
|
||||||
// Info Options
|
|
||||||
'showServerInfo',
|
|
||||||
'showDiscoZoneInfo',
|
|
||||||
'showShipPathsInfo',
|
|
||||||
'showIslandNames',
|
|
||||||
'showLines',
|
|
||||||
'showBackground',
|
|
||||||
|
|
||||||
// S3 Options
|
|
||||||
'LocalS3URL',
|
|
||||||
'LocalS3AccessKeyId',
|
|
||||||
'LocalS3SecretKey',
|
|
||||||
'LocalS3BucketName',
|
|
||||||
'LocalS3Region',
|
|
||||||
|
|
||||||
// Unsorted...
|
|
||||||
'shipPathsIdGenerator',
|
|
||||||
'idGenerator',
|
|
||||||
'regionsIdGenerator',
|
|
||||||
];
|
|
||||||
|
|
||||||
RawSubData.forEach(item => {
|
|
||||||
output[item] = this[item];
|
|
||||||
});
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,14 @@
|
||||||
import {BaseConfig} from "./abstract/baseConfig.model";
|
import {BaseConfig} from "./abstract/baseConfig.model";
|
||||||
import { ToJSON } from "./util/toJson";
|
import { Deserialize } from "./util/deserialize.model";
|
||||||
|
|
||||||
export class SharedLogConfigModel extends BaseConfig implements ToJSON {
|
export class SharedLogConfigModel extends BaseConfig implements Deserialize {
|
||||||
public FetchRateSec: number = 60;
|
public FetchRateSec: number = 60;
|
||||||
public SnapshotCleanupSec: number = 900;
|
public SnapshotCleanupSec: number = 900;
|
||||||
public SnapshotRateSec: number = 1800;
|
public SnapshotRateSec: number = 1800;
|
||||||
public SnapshotExpirationHours: number = 48;
|
public SnapshotExpirationHours: number = 48;
|
||||||
|
|
||||||
constructor(raw?:Partial<SharedLogConfigModel>) {
|
public deserialize(input: any): this {
|
||||||
super();
|
Object.assign(this, input);
|
||||||
Object.assign(this, raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
public toJSON() {
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,10 @@
|
||||||
import {BaseConfig} from "./abstract/baseConfig.model";
|
import {BaseConfig} from "./abstract/baseConfig.model";
|
||||||
import { ToJSON } from "./util/toJson";
|
import { Deserialize } from "./util/deserialize.model";
|
||||||
|
|
||||||
export class TravelDataConfigModel extends BaseConfig implements ToJSON {
|
export class TravelDataConfigModel extends BaseConfig implements Deserialize {
|
||||||
|
|
||||||
constructor(raw?:Partial<TravelDataConfigModel>) {
|
public deserialize(input: any): this {
|
||||||
super();
|
Object.assign(this, input);
|
||||||
Object.assign(this, raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
public toJSON() {
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
import {BaseConfig} from "./abstract/baseConfig.model";
|
import {BaseConfig} from "./abstract/baseConfig.model";
|
||||||
import { ToJSON } from "./util/toJson";
|
import {Deserialize} from "./util/deserialize.model";
|
||||||
|
import {Serialize} from "./util/serialize.model";
|
||||||
|
import {PegjsService} from "../services/pegjs.service";
|
||||||
|
|
||||||
export class TribeLogConfigModel extends BaseConfig implements ToJSON {
|
export class TribeLogConfigModel extends BaseConfig implements Deserialize {
|
||||||
public MaxRedisEntries: number = 1000;
|
public MaxRedisEntries: number = 1000;
|
||||||
|
|
||||||
constructor(raw?:Partial<TribeLogConfigModel>) {
|
public deserialize(raw: any): this {
|
||||||
super();
|
|
||||||
Object.assign(this, raw);
|
Object.assign(this, raw);
|
||||||
}
|
|
||||||
|
|
||||||
public toJSON() {
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
export interface DeserializeJson {
|
export interface Deserialize {
|
||||||
deserialize(input: any): this;
|
deserialize(input: any): this;
|
||||||
}
|
}
|
||||||
3
src/app/models/util/serialize.model.ts
Normal file
3
src/app/models/util/serialize.model.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export interface Serialize {
|
||||||
|
serialize(): any;
|
||||||
|
}
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
export interface ToAtlas {
|
|
||||||
toString(): string;
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
export interface ToJSON {
|
|
||||||
toJSON(): object;
|
|
||||||
}
|
|
||||||
|
|
@ -1,2 +1,8 @@
|
||||||
<p>config works!</p>
|
<div class="row">
|
||||||
<input [(ngModel)]="server.serverGrid.WorldFriendlyName">
|
<div class="col-2 mt-3">
|
||||||
|
<button class="btn btn-primary btn-block" [routerLink]="['grid']">Grid Settings</button>
|
||||||
|
<button class="btn btn-primary btn-block" [routerLink]="['dbs']">DB Settings</button>
|
||||||
|
<button class="btn btn-primary btn-block" [routerLink]="['quests']">Quest Settings</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-10"><router-outlet></router-outlet></div>
|
||||||
|
</div>
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ConfigComponent } from './config.component';
|
|
||||||
|
|
||||||
describe('ConfigComponent', () => {
|
|
||||||
let component: ConfigComponent;
|
|
||||||
let fixture: ComponentFixture<ConfigComponent>;
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [ ConfigComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ConfigComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -13,5 +13,4 @@ export class ConfigComponent implements OnInit {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
src/app/pages/config/dbs/dbs.component.html
Normal file
15
src/app/pages/config/dbs/dbs.component.html
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 mt-3">
|
||||||
|
<h2>Database Settings</h2>
|
||||||
|
<ngb-accordion>
|
||||||
|
<ngb-panel *ngFor="let db of dbs; let i = index" title="{{ db.Name }}">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-text id="db-{{ i }}-name" label="Name" [(text)]="db.Name"></app-text>
|
||||||
|
<app-text id="db-{{ i }}-URL" label="URL" [(text)]="db.URL"></app-text>
|
||||||
|
<app-number id="db-{{ i }}-Port" label="Port" [(number)]="db.Port"></app-number>
|
||||||
|
<app-password id="db-{{ i }}-Password" label="Password" [(password)]="db.Password"></app-password>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
</ngb-accordion>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
19
src/app/pages/config/dbs/dbs.component.ts
Normal file
19
src/app/pages/config/dbs/dbs.component.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Server } from "../../../server";
|
||||||
|
import { DatabaseConnectionModel } from "../../../models/databaseConnection.model";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-dbs',
|
||||||
|
templateUrl: './dbs.component.html'
|
||||||
|
})
|
||||||
|
export class DbsComponent implements OnInit {
|
||||||
|
dbs: DatabaseConnectionModel[];
|
||||||
|
|
||||||
|
constructor(private server: Server) {
|
||||||
|
this.dbs = server.serverGrid.DatabaseConnections;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
102
src/app/pages/config/grid/grid.component.html
Normal file
102
src/app/pages/config/grid/grid.component.html
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 mt-3">
|
||||||
|
<h2>Grid Settings</h2>
|
||||||
|
<ngb-accordion>
|
||||||
|
<ngb-panel id="toggle-generalSettings" title="World Settings">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-text id="WorldFriendlyName" label="Name" [(text)]="grid.WorldFriendlyName"
|
||||||
|
help="Name shown on Atlas server listings for your server"></app-text>
|
||||||
|
<app-text id="WorldAtlasId" label="Atlas ID" [(text)]="grid.WorldAtlasId"
|
||||||
|
help="Unique ID used for joining multiple servers together in multi-host setups"></app-text>
|
||||||
|
<app-password id="WorldAtlasPassword" label="Password"
|
||||||
|
[(password)]="grid.WorldAtlasPassword"
|
||||||
|
help="Password used for connecting to your Server"></app-password>
|
||||||
|
<app-text id="ModIDs" label="Mod IDs" [(text)]="grid.ModIDs"
|
||||||
|
help="Comma separated list of Mod IDs from Steam Workshop"></app-text>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
<ngb-panel id="toggle-gridSettings" title="Grid Size Settings">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-number id="gridSize" label="Grid Size" [(number)]="grid.gridSize"
|
||||||
|
help="Size in Unreal Units per Cell. Recommended default & maximum 1,400,000"></app-number>
|
||||||
|
<app-number id="totalGridsX" label="Total Grids X" [(number)]="grid.totalGridsX"
|
||||||
|
help="Total number of Cells in X Direction"></app-number>
|
||||||
|
<app-number id="totalGridsY" label="Total Grids Y" [(number)]="grid.totalGridsY"
|
||||||
|
help="Total number of Cells in Y Direction"></app-number>
|
||||||
|
<app-number id="globalTransitionMinZ" label="Min Z Transition"
|
||||||
|
[(number)]="grid.globalTransitionMinZ"
|
||||||
|
help="Lowest Z height for transitions across cell borders"></app-number>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
<ngb-panel id="toggle-urlSettings" title="URL Settings">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-text id="MetaWorldURL" label="Meta World URL" [(text)]="grid.MetaWorldURL"></app-text>
|
||||||
|
<app-text id="AuthListURL" label="Auth List URL" [(text)]="grid.AuthListURL"></app-text>
|
||||||
|
<app-text id="MapImageURL" label="Map Image URL" [(text)]="grid.MapImageURL"></app-text>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
<ngb-panel id="toggle-timeOptions" title="Time Settings">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-text id="Day0" label="Day Zero" [(text)]="grid.Day0"></app-text>
|
||||||
|
<app-checkbox id="bUseUTCTime" label="Use UTC" [(checkbox)]="grid.bUseUTCTime"></app-checkbox>
|
||||||
|
<app-number id="columnUTCOffset" label="UTC Offset" [(number)]="grid.columnUTCOffset"></app-number>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
<ngb-panel id="toggle-1" title="Local S3 Settings">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-text id="LocalS3URL" label="URL" [(text)]="grid.LocalS3URL"></app-text>
|
||||||
|
<app-text id="LocalS3AccessKeyID" label="Access Key ID"
|
||||||
|
[(text)]="grid.LocalS3AccessKeyId"></app-text>
|
||||||
|
<app-password id="LocalS3SecretKey" label="Secret Key"
|
||||||
|
[(password)]="grid.LocalS3SecretKey"></app-password>
|
||||||
|
<app-text id="LocalS3BucketName" label="Bucket Name" [(text)]="grid.LocalS3BucketName"></app-text>
|
||||||
|
<app-text id="LocalS3Region" label="Region" [(text)]="grid.LocalS3Region"></app-text>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
<ngb-panel title="Tribe Log Settings">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-number id="Tribe-MaxRedisEntries" label="Max Redis Entries" [(number)]="tribeLog.MaxRedisEntries"></app-number>
|
||||||
|
<app-text id="Tribe-BackupMode" label="Backup Mode" [(text)]="tribeLog.BackupMode"></app-text>
|
||||||
|
<app-number id="Tribe-MaxFileHistory" label="Max File History" [(number)]="tribeLog.MaxFileHistory"></app-number>
|
||||||
|
<app-text id="Tribe-HttpBackupURL" label="Http Backup URL" [(text)]="tribeLog.HttpBackupURL"></app-text>
|
||||||
|
<app-text id="Tribe-HttpAPIKey" label="HTTP API Key" [(text)]="tribeLog.HttpAPIKey"></app-text>
|
||||||
|
<app-text id="Tribe-S3URL" label="S3 URL" [(text)]="tribeLog.S3URL"></app-text>
|
||||||
|
<app-text id="Tribe-S3AccessKeyId" label="S3 Access Key ID" [(text)]="tribeLog.S3AccessKeyId"></app-text>
|
||||||
|
<app-password id="Tribe-S3SecretKey" label="S3 Secret Key" [(password)]="tribeLog.S3SecretKey"></app-password>
|
||||||
|
<app-text id="Tribe-S3BucketName" label="S3 Bucket Name" [(text)]="tribeLog.S3BucketName"></app-text>
|
||||||
|
<app-text id="Tribe-S3KeyPrefix" label="S3 Key Prefix" [(text)]="tribeLog.S3KeyPrefix"></app-text>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
<ngb-panel title="Shared Log Settings">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-number id="Shared-FetchRateSec" label="Fetch Rate (s)" [(number)]="sharedLog.FetchRateSec"></app-number>
|
||||||
|
<app-number id="Shared-SnapshotRateSec" label="Snapshot Rate (s)" [(number)]="sharedLog.SnapshotRateSec"></app-number>
|
||||||
|
<app-number id="Shared-SnapshotCleanupSec" label="Snapshot Cleanup (s)" [(number)]="sharedLog.SnapshotCleanupSec"></app-number>
|
||||||
|
<app-number id="Shared-SnapshotExpirationHours" label="Snapshot Expiration (h)" [(number)]="sharedLog.SnapshotExpirationHours"></app-number>
|
||||||
|
<app-text id="Shared-BackupMode" label="Backup Mode" [(text)]="sharedLog.BackupMode"></app-text>
|
||||||
|
<app-number id="Shared-MaxFileHistory" label="Max File History" [(number)]="sharedLog.MaxFileHistory"></app-number>
|
||||||
|
<app-text id="Shared-HttpBackupURL" label="Http Backup URL" [(text)]="sharedLog.HttpBackupURL"></app-text>
|
||||||
|
<app-text id="Shared-HttpAPIKey" label="HTTP API Key" [(text)]="sharedLog.HttpAPIKey"></app-text>
|
||||||
|
<app-text id="Shared-S3URL" label="S3 URL" [(text)]="sharedLog.S3URL"></app-text>
|
||||||
|
<app-text id="Shared-S3AccessKeyId" label="S3 Access Key ID" [(text)]="sharedLog.S3AccessKeyId"></app-text>
|
||||||
|
<app-password id="Shared-S3SecretKey" label="S3 Secret Key" [(password)]="sharedLog.S3SecretKey"></app-password>
|
||||||
|
<app-text id="Shared-S3BucketName" label="S3 Bucket Name" [(text)]="sharedLog.S3BucketName"></app-text>
|
||||||
|
<app-text id="Shared-S3KeyPrefix" label="S3 Key Prefix" [(text)]="sharedLog.S3KeyPrefix"></app-text>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
<ngb-panel title="Travel Data Settings">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-text id="Travel-BackupMode" label="Backup Mode" [(text)]="travelData.BackupMode"></app-text>
|
||||||
|
<app-number id="Travel-MaxFileHistory" label="Max File History" [(number)]="travelData.MaxFileHistory"></app-number>
|
||||||
|
<app-text id="Travel-HttpBackupURL" label="Http Backup URL" [(text)]="travelData.HttpBackupURL"></app-text>
|
||||||
|
<app-text id="Travel-HttpAPIKey" label="HTTP API Key" [(text)]="travelData.HttpAPIKey"></app-text>
|
||||||
|
<app-text id="Travel-S3URL" label="S3 URL" [(text)]="travelData.S3URL"></app-text>
|
||||||
|
<app-text id="Travel-S3AccessKeyId" label="S3 Access Key ID" [(text)]="travelData.S3AccessKeyId"></app-text>
|
||||||
|
<app-password id="Travel-S3SecretKey" label="S3 Secret Key" [(password)]="travelData.S3SecretKey"></app-password>
|
||||||
|
<app-text id="Travel-S3BucketName" label="S3 Bucket Name" [(text)]="travelData.S3BucketName"></app-text>
|
||||||
|
<app-text id="Travel-S3KeyPrefix" label="S3 Key Prefix" [(text)]="travelData.S3KeyPrefix"></app-text>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
</ngb-accordion>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
27
src/app/pages/config/grid/grid.component.ts
Normal file
27
src/app/pages/config/grid/grid.component.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ServerGridModel } from "../../../models/serverGrid.model";
|
||||||
|
import { Server } from "../../../server";
|
||||||
|
import { TribeLogConfigModel } from "../../../models/tribeLogConfig.model";
|
||||||
|
import { SharedLogConfigModel } from "../../../models/sharedLogConfig.model";
|
||||||
|
import { TravelDataConfigModel } from "../../../models/travelDataConfig.model";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-grid',
|
||||||
|
templateUrl: './grid.component.html'
|
||||||
|
})
|
||||||
|
export class GridComponent implements OnInit {
|
||||||
|
private grid: ServerGridModel;
|
||||||
|
private tribeLog: TribeLogConfigModel;
|
||||||
|
private sharedLog: SharedLogConfigModel;
|
||||||
|
private travelData: TravelDataConfigModel;
|
||||||
|
|
||||||
|
constructor(private server: Server) {
|
||||||
|
this.grid = server.serverGrid;
|
||||||
|
this.tribeLog = server.serverGrid.TribeLogConfig;
|
||||||
|
this.sharedLog = server.serverGrid.SharedLogConfig;
|
||||||
|
this.travelData = server.serverGrid.TravelDataConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/app/pages/config/quests/quests.component.html
Normal file
67
src/app/pages/config/quests/quests.component.html
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 mt-3 mb-3">
|
||||||
|
<h2>Quest Entries</h2>
|
||||||
|
<ngb-accordion>
|
||||||
|
<ngb-panel *ngFor="let quest of quests; let i = index" id="toggle-{{ i }}" title="{{ quest.QuestName }}">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<app-text id="{{ i }}-QuestName" label="Name" [(text)]="quest.QuestName"></app-text>
|
||||||
|
<app-number id="{{ i }}-QuestID" label="ID" [(number)]="quest.QuestID"></app-number>
|
||||||
|
<app-text id="{{ i }}-QuestDescription" label="Description"
|
||||||
|
[(text)]="quest.QuestDescription"></app-text>
|
||||||
|
<h6>Feat Unlocks
|
||||||
|
<button class="btn btn-primary btn-sm" (click)="addQuestFeat(quest)">+</button>
|
||||||
|
</h6>
|
||||||
|
<p *ngIf="quest.UnlockFeatNames === undefined">
|
||||||
|
<em>Click + above to add Feat Unlocks</em>
|
||||||
|
</p>
|
||||||
|
<app-text id="{{ i }}-{{ j }}-feat"
|
||||||
|
*ngFor="let feat of quest.UnlockFeatNames; index as j; trackBy: trackByFn"
|
||||||
|
label="Unlock {{ j }}" [(text)]="quest.UnlockFeatNames[j]" postButtonText="-"
|
||||||
|
(postButton)="removeQuestFeat(quest, j)"></app-text>
|
||||||
|
<h6>Engram Unlocks
|
||||||
|
<button class="btn btn-primary btn-sm" (click)="addEngramClass(quest)">+</button>
|
||||||
|
</h6>
|
||||||
|
<p *ngIf="quest.CompleteGiveEngramClasses === undefined">
|
||||||
|
<em>Click + above to add Engram Unlocks</em>
|
||||||
|
</p>
|
||||||
|
<app-text id="{{ i }}-{{ j }}-engram"
|
||||||
|
*ngFor="let engram of quest.CompleteGiveEngramClasses; index as j"
|
||||||
|
label="Engram {{ j }}" [(text)]="engram.blueprint" postButtonText="-"
|
||||||
|
(postButton)="removeEngramClass(quest, j)"></app-text>
|
||||||
|
<h6>Points of Interest
|
||||||
|
<button class="btn btn-primary btn-sm">+</button>
|
||||||
|
</h6>
|
||||||
|
<p *ngIf="quest.QuestPointsOfInterest === undefined">
|
||||||
|
<em>Click + above to add Point of Interest</em>
|
||||||
|
</p>
|
||||||
|
<div class="card mb-3" *ngFor="let poi of quest.QuestPointsOfInterest; index as j">
|
||||||
|
<div class="card-body">
|
||||||
|
<app-text id="{{ i }}-{{ j }}-poi-PointOfInterestName"
|
||||||
|
label="Name" [(text)]="poi.PointOfInterestName"></app-text>
|
||||||
|
<app-number id="{{ i }}-{{ j }}-poi-PointOfInterestID"
|
||||||
|
label="ID" [(number)]="poi.PointOfInterestID"></app-number>
|
||||||
|
<app-number id="{{ i }}-{{ j }}-poi-WorldMapPosition-X"
|
||||||
|
label="Map X Pos" [(number)]="poi.WorldMapPosition.X"></app-number>
|
||||||
|
<app-number id="{{ i }}-{{ j }}-poi-WorldMapPosition-Y"
|
||||||
|
label="Map Y Pos" [(number)]="poi.WorldMapPosition.Y"></app-number>
|
||||||
|
<app-text id="{{ i }}-{{ j }}-poi-CompletedIcon"
|
||||||
|
label="Completed Icon" [(text)]="poi.CompletedIcon.texture"></app-text>
|
||||||
|
<app-text id="{{ i }}-{{ j }}-poi-UncompletedIcon"
|
||||||
|
label="Uncompleted Icon" [(text)]="poi.UncompletedIcon.texture"></app-text>
|
||||||
|
<h6>Feat Unlocks
|
||||||
|
<button class="btn btn-primary btn-sm" (click)="addQuestFeat(poi)">+</button>
|
||||||
|
</h6>
|
||||||
|
<p *ngIf="poi.UnlockFeatNames === undefined">
|
||||||
|
<em>Click + above to add Feat Unlocks</em>
|
||||||
|
</p>
|
||||||
|
<app-text id="{{ i }}-{{ j }}-={{ k }}feat"
|
||||||
|
*ngFor="let feat of poi.UnlockFeatNames; index as k; trackBy: trackByFn"
|
||||||
|
label="Unlock {{ k }}" [(text)]="poi.UnlockFeatNames[k]" postButtonText="-"
|
||||||
|
(postButton)="removeQuestFeat(poi, k)"></app-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
</ngb-accordion>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
53
src/app/pages/config/quests/quests.component.ts
Normal file
53
src/app/pages/config/quests/quests.component.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Server } from "../../../server";
|
||||||
|
import { QuestEntryModel } from "../../../models/atlasData/questEntry.model";
|
||||||
|
import { BlueprintGeneratedClassModel } from "../../../models/atlasData/blueprintGeneratedClass.model";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-quests',
|
||||||
|
templateUrl: './quests.component.html'
|
||||||
|
})
|
||||||
|
|
||||||
|
export class QuestsComponent implements OnInit {
|
||||||
|
quests: QuestEntryModel[];
|
||||||
|
|
||||||
|
constructor(private server: Server) {
|
||||||
|
this.quests = server.serverGrid.globalGameplaySetup.QuestEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue with text arrays and editing jumps on each change.
|
||||||
|
trackByFn(index: any, item: any) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private addQuestFeat(quest) {
|
||||||
|
if (quest.UnlockFeatNames === undefined) {
|
||||||
|
quest.UnlockFeatNames = [];
|
||||||
|
}
|
||||||
|
quest.UnlockFeatNames.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
private removeQuestFeat(quest, j) {
|
||||||
|
quest.UnlockFeatNames.splice(j, 1);
|
||||||
|
if (quest.UnlockFeatNames.length === 0) {
|
||||||
|
quest.UnlockFeatNames = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private addEngramClass(quest) {
|
||||||
|
if (quest.CompleteGiveEngramClasses === undefined) {
|
||||||
|
quest.CompleteGiveEngramClasses = [];
|
||||||
|
}
|
||||||
|
quest.CompleteGiveEngramClasses.push(new BlueprintGeneratedClassModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
private removeEngramClass(quest, j) {
|
||||||
|
quest.CompleteGiveEngramClasses.splice(j, 1);
|
||||||
|
if (quest.CompleteGiveEngramClasses.length === 0) {
|
||||||
|
quest.UnlockFeatNames = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,21 +5,20 @@ import { ServerGridModel } from "./models/serverGrid.model";
|
||||||
export class Server {
|
export class Server {
|
||||||
private rawData: string = "";
|
private rawData: string = "";
|
||||||
private jsonData: object = {};
|
private jsonData: object = {};
|
||||||
public serverGrid: ServerGridModel = new ServerGridModel({});
|
public serverGrid: ServerGridModel = new ServerGridModel();
|
||||||
|
|
||||||
public load(raw) {
|
public load(raw) {
|
||||||
this.rawData = raw;
|
this.rawData = raw;
|
||||||
try {
|
try {
|
||||||
this.jsonData = JSON.parse(this.rawData);
|
this.jsonData = JSON.parse(this.rawData);
|
||||||
this.serverGrid = new ServerGridModel(this.jsonData);
|
this.serverGrid = new ServerGridModel().deserialize(this.jsonData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public save() {
|
public save() {
|
||||||
this.jsonData = this.serverGrid.toJSON();
|
this.rawData = JSON.stringify(this.serverGrid, null, 2);
|
||||||
this.rawData = JSON.stringify(this.jsonData);
|
|
||||||
return this.rawData;
|
return this.rawData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -25,11 +25,21 @@ export class PegjsService {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static format(input: object): string {
|
public static format(input: object, skipCurrentObject?: boolean): string {
|
||||||
return PegjsService.deparseJson(input)
|
return PegjsService.deparseJson(input, undefined, skipCurrentObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static deparseJson(input, key?) {
|
private static deparseJson(input, key?, skip?: boolean) {
|
||||||
|
// Call possible toJSON on object
|
||||||
|
if(!skip && typeof input === 'object' && typeof input.toJSON === 'function') {
|
||||||
|
input = input.toJSON();
|
||||||
|
}
|
||||||
|
// if(input !== undefined && input.hasOwnProperty('toJSON') && typeof input.toJSON === 'function') {
|
||||||
|
// console.log("calling toJSON!");
|
||||||
|
// console.log(input);
|
||||||
|
// input = input.toJSON();
|
||||||
|
// console.log(input);
|
||||||
|
// }
|
||||||
switch (typeof input) {
|
switch (typeof input) {
|
||||||
case "object":
|
case "object":
|
||||||
return PegjsService.deparseObject(input);
|
return PegjsService.deparseObject(input);
|
||||||
|
|
|
||||||
170195
src/serverGridExample.json
Normal file
170195
src/serverGridExample.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -7,6 +7,7 @@
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
"downlevelIteration": true,
|
"downlevelIteration": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue