// True numeric value binding ko.bindingHandlers.numericValue = { init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var underlyingObservable = valueAccessor(); var interceptor = ko.dependentObservable({ read: underlyingObservable, write: function (value) { if (!isNaN(value)) { underlyingObservable(parseFloat(value)); } } }); ko.bindingHandlers.value.init(element, function () { return interceptor }, allBindingsAccessor, viewModel, bindingContext); }, update: ko.bindingHandlers.value.update }; var editor = ace.edit("config-editor"); editor.setTheme("ace/theme/monokai"); editor.session.setMode("ace/mode/json"); var parser; $.get('js/atlas.pegjs', function (data) { parser = PEG.buildParser(data); }); var viewmodel = ko.mapping.fromJS({ // Server Argument Section "BaseServerArgs": "", "AdditionalCmdLineParams": "", // World Options "WorldFriendlyName": "New Server", "WorldAtlasId": "", "WorldAtlasPassword": "", "ModIDs": "", // Grid Options "gridSize": 1000, "totalGridsX": 1, "totalGridsY": 1, "coordsScaling": 0.000000000001, "globalTransitionMinZ": 0.0, // Image Paths "backgroundImgPath": "image.png", "discoZonesImagePath": "image.png", // URL Options "MetaWorldURL": "", "AuthListURL": "", "MapImageURL": "", // Time Options "Day0": "2019-01-09 20:28:56", "bUseUTCTime": false, "columnUTCOffset": 0.0, "lastImageOverride": "0001-01-01T00:00:00", // Info Options "showServerInfo": false, "showDiscoZoneInfo": false, "showShipPathsInfo": false, "showIslandNames": false, "showLines": false, "showBackground": false, // S3 Options "LocalS3URL": "", "LocalS3AccessKeyId": "", "LocalS3SecretKey": "", "LocalS3BucketName": "", "LocalS3Region": "", // Unsorted... "globalGameplaySetup": "", "shipPathsIdGenerator": 1, "idGenerator": 127, "regionsIdGenerator": 0, // Tribe Log Tab "TribeLogConfig": { // Main Options "MaxRedisEntries": 1000, "BackupMode": "off", "MaxFileHistory": 10, "HttpBackupURL": "", "HttpAPIKey": "", //S3 Options "S3URL": "", "S3AccessKeyId": "", "S3SecretKey": "", "S3BucketName": "", "S3KeyPrefix": "" }, // Travel Data Tab "TravelDataConfig": { // Main Options "BackupMode": "off", "MaxFileHistory": 10, "HttpBackupURL": "", "HttpAPIKey": "", //S3 Options "S3URL": "", "S3AccessKeyId": "", "S3SecretKey": "", "S3BucketName": "", "S3KeyPrefix": "" }, // Shared Log Tab "SharedLogConfig": { // Main Options "FetchRateSec": 60, "SnapshotCleanupSec": 900, "SnapshotRateSec": 1800, "SnapshotExpirationHours": 48, "BackupMode": "off", "MaxFileHistory": 10, "HttpBackupURL": "", "HttpAPIKey": "", //S3 Options "S3URL": "", "S3AccessKeyId": "", "S3SecretKey": "", "S3BucketName": "", "S3KeyPrefix": "" }, // Databases Tab "DatabaseConnections": [ { "Name": "Default", "URL": "127.0.0.1", "Port": 6390, "Password": "" }, { "Name": "TribeDB", "URL": "127.0.0.1", "Port": 6390, "Password": "" }, { "Name": "TravelDataDB", "URL": "127.0.0.1", "Port": 6390, "Password": "" }, { "Name": "TerritoryDB", "URL": "127.0.0.1", "Port": 6390, "Password": "" }, { "Name": "LogDB", "URL": "127.0.0.1", "Port": 6390, "Password": "" } ], // Servers Tab "servers": [], "spawnerOverrideTemplates": [], "shipPaths": [], "serverTemplates": [], // ?!?! "OverrideShooterGameModeDefaultGameIni": {} }); ko.applyBindings(viewmodel); configToEditor(); function editorToConfig() { ko.mapping.fromJSON(editor.getValue(), viewmodel); } function configToEditor() { var interim = ko.mapping.toJS(viewmodel); // coordsScaling may need special care? //interim.coordsScaling = Number(interim.coordsScaling).toFixed(12); editor.setValue(ko.toJSON(interim, null, 2)); } function addDatabase() { var newDB = { "Name": ko.observable("NewDB"), "URL": ko.observable("127.0.0.1"), "Port": ko.observable(6390), "Password": ko.observable("") }; viewmodel.DatabaseConnections.push(newDB); } function removeDatabase(obj) { viewmodel.DatabaseConnections.remove(obj); } function addServer() { var newServer = { // Basic Data "name": ko.observable("Server Name"), "serverTemplateName": ko.observable("Template Name"), "ip": ko.observable("127.0.0.1"), "port": ko.observable(29145), "gamePort": ko.observable(3045), "seamlessDataPort": ko.observable(31029), "gridX": ko.observable(0), "gridY": ko.observable(0), "MachineIdTag": ko.observable(""), "isHomeServer": ko.observable(false), "AdditionalCmdLineParams": ko.observable(""), // Biome Options "GlobalBiomeSeamlessServerGridPreOffsetValues": ko.observable(""), "GlobalBiomeSeamlessServerGridPreOffsetValuesOceanWater": ko.observable(""), // Override Options "OceanDinoDepthEntriesOverride": ko.observable(""), "OceanEpicSpawnEntriesOverrideValues": ko.observable(""), "oceanFloatsamCratesOverride": ko.observable(""), "treasureMapLootTablesOverride": ko.observable(""), "oceanEpicSpawnEntriesOverrideTemplateName": ko.observable(""), "NPCShipSpawnEntriesOverrideTemplateName": ko.observable(""), "regionOverrides": ko.observable(""), // Style Options "waterColorR": ko.observable(0.0), "waterColorG": ko.observable(0.0), "waterColorB": ko.observable(0.0), "skyStyleIndex": ko.observable(0), // Misc Options "floorZDist": ko.observable(0), "utcOffset": ko.observable(0), "transitionMinZ": ko.observable(0), "serverIslandPointsMultiplier": ko.observable(1.0), // Date Options "lastModified": ko.observable("2019-04-14T21:32:04.7310108Z"), "lastImageOverride": ko.observable("0001-01-01T00:00:00"), // Boolean Options "islandLocked": ko.observable(true), "discoLocked": ko.observable(true), "pathsLocked": ko.observable(false), // Tabled Options "sublevels": ko.observableArray([]), "extraSublevels": ko.observableArray([]), "totalExtraSublevels": ko.observableArray([]), "islandInstances": ko.observableArray([]), "discoZones": ko.observableArray([]), "spawnRegions": ko.observableArray([]), // ??? "OverrideShooterGameModeDefaultGameIni": ko.observable({}) }; viewmodel.servers.push(newServer); } function removeServer(obj) { viewmodel.servers.remove(obj); } var deparseEditor = ace.edit("deparse-editor"); deparseEditor.setTheme("ace/theme/monokai"); deparseEditor.session.setMode("ace/mode/json"); var activeDeparseEdit; function deparseEdit(data) { activeDeparseEdit = data.value; $('#deparse-modal').on('hide.bs.modal', function () { cancelDeparseEdit(); }); $('#deparse-modal').modal('show'); var parsed = parser.parse(activeDeparseEdit()); deparseEditor.setValue(ko.toJSON(parsed, null, 2)); } function cancelDeparseEdit() { activeDeparseEdit = undefined; $('#deparse-modal').off('hide.bs.modal'); $('#deparse-modal').modal('hide'); } function saveDeparseEdit() { $('#deparse-modal').off('hide.bs.modal'); $('#deparse-modal').modal('hide'); var parsed = JSON.parse(deparseEditor.getValue()); activeDeparseEdit(deparseJson(parsed)); activeDeparseEdit = undefined; } var rawEditor = ace.edit("raw-editor"); rawEditor.setTheme("ace/theme/monokai"); rawEditor.session.setMode("ace/mode/json"); var activeRawEdit; function rawEdit(data) { activeRawEdit = data; $('#raw-modal').on('hide.bs.modal', function () { cancelRawEdit(); }); $('#raw-modal').modal('show'); rawEditor.setValue(ko.toJSON(ko.mapping.toJS(activeRawEdit), null, 2)); } function cancelRawEdit() { activeDeparseEdit = undefined; $('#raw-modal').off('hide.bs.modal'); $('#raw-modal').modal('hide'); } function saveRawEdit() { $('#raw-modal').off('hide.bs.modal'); $('#raw-modal').modal('hide'); ko.mapping.fromJSON(rawEditor.getValue(), {}, activeRawEdit); activeRawEdit = undefined; } function addServerSubLevel(obj) { var newSubLevel = { "id": ko.observable(0), "name": ko.observable("Map_Name"), "additionalTranslationX": ko.observable(0), "additionalTranslationY": ko.observable(0), "additionalTranslationZ": ko.observable(0), "additionalRotationPitch": ko.observable(0), "additionalRotationYaw": ko.observable(0), "additionalRotationRoll": ko.observable(0), "landscapeMaterialOverride": ko.observable(-1) }; obj.sublevels.push(newSubLevel); } function removeServerSubLevel(obj, e) { ko.contextFor(e.target).$parent.sublevels.remove(obj); } function addServerIslandInstance(obj) { var newIslandInstance = { "id": ko.observable(0), "name": ko.observable("Island_Name"), "spawnerOverrides": ko.observable({}), "minTreasureQuality": ko.observable(-1.0), "maxTreasureQuality": ko.observable(-1.0), "useNpcVolumesForTreasures": ko.observable(false), "useLevelBoundsForTreasures": ko.observable(true), "prioritizeVolumesForTreasures": ko.observable(false), "islandPoints": ko.observable(-1), "islandTreasureBottleSupplyCrateOverrides": ko.observable(""), "islandWidth": ko.observable(0), "islandHeight": ko.observable(0), "worldX": ko.observable(0), "worldY": ko.observable(0), "rotation": ko.observable(0) }; obj.islandInstances.push(newIslandInstance); } function removeServerIslandInstance(obj, e) { ko.contextFor(e.target).$parent.islandInstances.remove(obj); } function addServerDiscoveryZone(obj) { var newDiscoveryZone = { "id": ko.observable(0), "name": ko.observable("New Discovery Zone"), "sizeX": ko.observable(0), "sizeY": ko.observable(0), "sizeZ": ko.observable(0), "xp": ko.observable(0), "bIsManuallyPlaced": ko.observable(false), "explorerNoteIndex": ko.observable(0), "allowSea": ko.observable(false), "worldX": ko.observable(0), "worldY": ko.observable(0), "rotation": ko.observable(0) }; obj.discoZones.push(newDiscoveryZone); } function removeServerDiscoveryZone(obj, e) { ko.contextFor(e.target).$parent.discoZones.remove(obj); } function addServerSpawnRegion(obj) { var newServerSpawnRegion = { "name": ko.observable("") }; obj.spawnRegions.push(newServerSpawnRegion); } function removeServerSpawnRegion(obj, e) { ko.contextFor(e.target).$parent.spawnRegions.remove(obj); } function addExtraSubLevels(obj) { var newSubLevel = ''; obj.extraSublevels.push(newSubLevel); } function removeExtraSubLevels(obj, e) { ko.contextFor(e.target).$parent.extraSublevels.remove(obj) } function addTotalExtraSubLevels(obj) { var newSubLevel = ''; obj.totalExtraSublevels.push(newSubLevel); } function removeTotalExtraSubLevels(obj, e) { ko.contextFor(e.target).$parent.totalExtraSublevels.remove(obj) } function addSpawner() { var newSpawner = { "Name": ko.observable("New Spawner"), "NPCSpawnEntries": ko.observable(""), "NPCSpawnLimits": ko.observable(""), "MaxDesiredNumEnemiesMultiplier": ko.observable(1) }; viewmodel.spawnerOverrideTemplates.push(newSpawner); } function removeSpawner(obj) { viewmodel.spawnerOverrideTemplates.remove(obj); } function addShip() { var newShip = { "PathName": ko.observable("New Ship"), "PathId": ko.observable(1), "AutoSpawnShipClass": ko.observable(""), "AutoSpawnEveryUTCInterval": ko.observable(21600), "autoSpawn": ko.observable(true), "Nodes": ko.observableArray([]) }; viewmodel.shipPaths.push(newShip); } function removeShip(obj) { viewmodel.shipPaths.remove(obj); } function addShipNode(obj) { var newNode = { "controlPointsDistance": ko.observable(0), "worldX": ko.observable(0), "worldY": ko.observable(0), "rotation": ko.observable(0) }; obj.Nodes.push(newNode); } function removeShipNode(obj, e) { ko.contextFor(e.target).$parent.Nodes.remove(obj) } function addTemplate() { var newTemplate = { // Basic Data "name": ko.observable("New Template"), "ip": ko.observable("127.0.0.1"), "port": ko.observable(50000), "gamePort": ko.observable(6666), "seamlessDataPort": ko.observable(27000), "gridX": ko.observable(0), "gridY": ko.observable(0), "MachineIdTag": ko.observable(""), "isHomeServer": ko.observable(false), "AdditionalCmdLineParams": ko.observable(""), // Biome Options "GlobalBiomeSeamlessServerGridPreOffsetValues": ko.observable(""), "GlobalBiomeSeamlessServerGridPreOffsetValuesOceanWater": ko.observable(""), // Override Options "OceanDinoDepthEntriesOverride": ko.observable(""), "OceanEpicSpawnEntriesOverrideValues": ko.observable(""), "oceanFloatsamCratesOverride": ko.observable(""), "treasureMapLootTablesOverride": ko.observable(""), "oceanEpicSpawnEntriesOverrideTemplateName": ko.observable(""), "NPCShipSpawnEntriesOverrideTemplateName": ko.observable(""), "regionOverrides": ko.observable(""), // Style Options "templateColorR": ko.observable(0.0), "templateColorG": ko.observable(0.0), "templateColorB": ko.observable(0.0), "waterColorR": ko.observable(0.5), "waterColorG": ko.observable(0.1), "waterColorB": ko.observable(0.1), "skyStyleIndex": ko.observable(2), // Misc Options "floorZDist": ko.observable(0), "utcOffset": ko.observable(0), "transitionMinZ": ko.observable(0), "serverIslandPointsMultiplier": ko.observable(1.0), // Date Options "lastModified": ko.observable("0001-01-01T00:00:00"), "lastImageOverride": ko.observable("0001-01-01T00:00:00"), // Boolean Options "islandLocked": ko.observable(false), "discoLocked": ko.observable(false), "pathsLocked": ko.observable(false), // Long Tables "sublevels": ko.observableArray([]), "islandInstances": ko.observableArray([]), "discoZones": ko.observableArray([]), // Mini Tables "spawnRegions": ko.observableArray([]), "extraSublevels": ko.observableArray([]), "totalExtraSublevels": ko.observableArray([]), // ???? Will just have to have a custom JSON editor... "OverrideShooterGameModeDefaultGameIni": ko.observable({}) }; viewmodel.serverTemplates.push(newTemplate); } function removeTemplate(obj) { viewmodel.serverTemplates.remove(obj); }