var channelIps = ["35.155.204.207", "52.26.82.74", "34.217.205.66", "54.148.188.235", "54.218.157.183", "54.68.160.34", "52.25.78.39", "52.33.249.126", "34.218.141.142", "54.148.170.23", "54.191.142.56", "54.201.184.26", "52.13.185.207", "34.215.228.37", "54.187.177.143", "54.203.83.148", "35.161.183.101", "52.43.83.76", "54.69.114.137", "54.148.137.49", "54.212.109.33", "44.230.255.51", "100.20.116.83", "54.188.84.22", "34.215.170.50", "54.184.162.28", "54.185.209.29", "52.12.53.225", "54.189.33.238", "54.188.84.238"]; var channelIps2 = { Reboot : ["35.155.204.207", "52.26.82.74", "34.217.205.66", "54.148.188.235", "54.218.157.183", "54.68.160.34", "52.25.78.39", "52.33.249.126", "34.218.141.142", "54.148.170.23", "54.191.142.56", "54.201.184.26", "52.13.185.207", "34.215.228.37", "54.187.177.143", "54.203.83.148", "35.161.183.101", "52.43.83.76", "54.69.114.137", "54.148.137.49", "54.212.109.33", "44.230.255.51", "100.20.116.83", "54.188.84.22", "34.215.170.50", "54.184.162.28", "54.185.209.29", "52.12.53.225", "54.189.33.238", "54.188.84.238"], Scania : ["35.163.4.248 ", "54.69.121.239", "52.27.135.94", "34.218.55.122", "54.213.105.170", "52.37.131.173", "52.38.110.221", "50.112.158.189", "34.215.85.101", "54.191.76.216", "54.191.254.95", "50.112.211.236", "35.165.21.160", "34.211.249.74", "52.43.74.100", "34.209.206.177", "34.214.52.19", "54.189.248.141", "34.208.240.38", "54.245.14.209"], Bera : ["54.186.151.49", "54.214.207.253", "34.214.214.251", "35.165.105.161", "35.167.16.143", "52.40.39.138", "54.68.47.217", "52.35.241.179", "34.218.68.31", "52.43.9.29", "54.213.64.154", "52.25.121.0", "54.148.5.57", "35.161.154.148", "54.203.140.45", "35.163.184.1", "34.218.100.191", "52.38.89.169", "52.88.17.178", "52.27.189.124" ], Elysium : [ "54.214.132.190", "54.245.208.58", "35.165.10.219", "54.214.75.83", "35.163.91.77", "35.166.234.61", "52.43.231.158", "52.35.100.28", "54.70.100.207", "35.163.79.48", "52.32.142.22", "54.186.3.5", "34.211.210.222", "35.166.32.116", "54.186.75.108", "52.37.9.209", "52.37.174.51", "52.32.10.100", "54.203.45.149", "52.41.244.230"], Aurora : ["52.26.44.15", "52.88.199.249", "54.71.159.23", "54.200.197.85", "52.24.108.169", "52.32.48.160", "52.27.243.250", "54.203.90.46", "54.148.240.123", "35.164.217.126", "52.36.214.18", "35.162.50.9", "52.40.100.64", "52.39.159.3", "34.216.36.199", "34.213.140.179", "54.203.178.92", "54.214.75.143", "52.24.61.30", "34.208.168.106"], Burning : [ "52.26.44.15", "52.88.199.249", "54.71.159.23", "54.200.197.85", "52.24.108.169", "52.32.48.160", "52.27.243.250", "54.203.90.46", "54.148.240.123", "35.164.217.126", "52.36.214.18", "35.162.50.9", "52.40.100.64", "52.39.159.3", "34.216.36.199", "34.213.140.179", "54.203.178.92", "54.214.75.143", "52.24.61.30", "34.208.168.106"] }; function characterTracking() { startCharTracking(); var statSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Character Stats"); var nameCell = statSheet.getRange("Character Stats!B2"); var ign = nameCell.getValue(); if(!ign) { throw new Error("IGN cell is empty (Character Stats)."); } var classCell = statSheet.getRange("Character Stats!E3"); var classId = classCell.getValue(); if(!classId) { throw new Error("Class cell is empty (Character Stats)"); } var settingsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet Settings"); var timezoneCell = settingsSheet.getRange("Sheet Settings!D5"); var timezone = timezoneCell.getValue(); if(!timezone) { throw new Error("Timezone Cell is empty (Sheet Settings)."); } var overallUrl = "https://maplestory.nexon.net/api/ranking?id=overall&id2=legendary&rebootIndex=0&character_name=" + ign + "&page_index=1" //overall var overallContent = UrlFetchApp.fetch(overallUrl).getContentText(); var overallJson = JSON.parse(overallContent)[0]; var rebootIndex = overallJson.WorldID == 45 ? 1 : 2; var worldUrl = "https://maplestory.nexon.net/api/ranking?id=world&id2="+ overallJson.WorldID + " &character_name=" + ign + "&page_index=1"; var legionUrl = "https://maplestory.nexon.net/api/ranking?id=legion&id2=45&character_name=" + ign + "&page_index=1"; var classUrl = "https://maplestory.nexon.net/api/ranking?id=job&id2=" + classId + "&character_name=" + ign + "&rebootIndex=" + rebootIndex + "&page_index=1"; //world class var rankingUrl = "https://maplestory.nexon.net/api/ranking?id=overall&id2=legendary&rebootIndex=" + rebootIndex + "&character_name=" + ign + "&page_index=1"; var overallClassUrl = "https://maplestory.nexon.net/api/ranking?id=job&id2=" + classId + "&character_name=" + ign + "&rebootIndex=0&page_index=1"; //overall class var rankingContent = UrlFetchApp.fetch(rankingUrl).getContentText(); var rankJson = JSON.parse(rankingContent)[0]; var worldContent = UrlFetchApp.fetch(worldUrl).getContentText(); var worldJson = JSON.parse(worldContent)[0]; var legionContent = UrlFetchApp.fetch(legionUrl).getContentText(); var legionJson = JSON.parse(legionContent); var classContent = UrlFetchApp.fetch(classUrl).getContentText(); var classJson = JSON.parse(classContent)[0]; var overallClassContent = UrlFetchApp.fetch(overallClassUrl).getContentText(); var overallClassJson = JSON.parse(overallClassContent)[0]; var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("EXPTracking"); var row = sheet.getLastRow(); var dd = Utilities.formatDate(new Date(), timezone, "MM/dd/yyyy"); if(row != 1) { var lastRowDate = Utilities.formatDate(sheet.getRange("EXPTracking!A" + row).getValue(), "GMT", "MM/dd/yyyy"); if(lastRowDate != dd) { row += 1; } } else { row += 1 } var cellData = [[]] if(legionJson.length > 0) { legionJson = legionJson[0] cellData = [[dd, rankJson.CharacterName, rankJson.Level, rankJson.Exp, rankJson.Rank, legionJson.LegionLevel, legionJson.RaidPower, rankJson.CharacterImgUrl, rankJson.Gap * -1 ,classJson.Gap * -1, classJson.Rank, overallJson.Rank, overallJson.Gap * -1, overallClassJson.Rank, overallClassJson.Gap * -1,]] } else { cellData = [[dd, rankJson.CharacterName, rankJson.Level, rankJson.Exp, rankJson.Rank, "", "", rankJson.CharacterImgUrl, rankJson.Gap * -1 ,classJson.Gap * -1, classJson.Rank, overallJson.Rank, overallJson.Gap * -1, overallClassJson.Rank, overallClassJson.Gap * -1]] } sheet.getRange(row, 1, 1, 15).setValues(cellData) } function channelScheduler() { var properties = PropertiesService.getScriptProperties(); var channelStatusCounter = properties.getProperty('channelStatusCounter'); var lastManualPing = properties.getProperty('lastManualPing'); console.log("Days since last manual update: " + (Date.now() - lastManualPing) / (24 * 1000 * 3600)); var settingsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet Settings"); var updateInvtervalCell = settingsSheet.getRange("Sheet Settings!D7") var updateInterval = updateInvtervalCell.getValue(); if(!updateInterval) { throw new Error("Update Interval cell is empty (Sheet Settings)."); } if(updateInterval == "OFF") { return } if(!channelStatusCounter) { channelStatusCounter = 0; } if(++channelStatusCounter >= +updateInterval && ((Date.now() - lastManualPing) / (24 * 1000 * 3600)) <= 7) { channelStatusCounter = 0; channelStatus(); } properties.setProperty('channelStatusCounter', channelStatusCounter); } function channelManual() { var properties = PropertiesService.getScriptProperties(); var lastManualPing = properties.getProperty('lastManualPing'); lastManualPing = Date.now(); properties.setProperty('lastManualPing', lastManualPing); channelStatus(); } function characterScheduler() { var properties = PropertiesService.getScriptProperties(); var characterStatusCounter = properties.getProperty('characterCounter'); var settingsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet Settings"); var updateInvtervalCell = settingsSheet.getRange("Sheet Settings!D6") var updateInterval = updateInvtervalCell.getValue(); if(!updateInterval) { throw new Error("Update Interval cell is empty (Sheet Settings)."); } if(updateInterval == "OFF") { return } if(!characterStatusCounter) { characterStatusCounter = 0; } if(++characterStatusCounter >= +updateInterval) { characterStatusCounter = 0; characterTracking(); } properties.setProperty('characterCounter', characterStatusCounter); } function legionScheduler() { var properties = PropertiesService.getScriptProperties(); var legionCounter = properties.getProperty('legionCounter'); var settingsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet Settings"); var updateInvtervalCell = settingsSheet.getRange("Sheet Settings!D6") var updateInterval = updateInvtervalCell.getValue(); if(!updateInterval) { throw new Error("Update Interval cell is empty (Sheet Settings)."); } if(updateInterval == "OFF") { return } if(!legionCounter) { legionCounter = 0; } if(++legionCounter >= +updateInterval) { legionCounter = 0; legionPlanning(); } properties.setProperty('legionCounter', legionCounter); } function channelStatus() { startPingTracking(); var settingsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet Settings"); var timezoneCell = settingsSheet.getRange("Sheet Settings!D5"); var timezone = timezoneCell.getValue(); if(!timezone) { throw new Error("Timezone cell is empty (Sheet Settings)."); } var statSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Character Stats"); var worldCell = statSheet.getRange("Character Stats!E4"); var world = worldCell.getValue(); if(!world) { throw new Error("World cell is empty (Character Stats)."); } var chStabilitySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Channel Stability"); var pingCapCell = chStabilitySheet.getRange("Channel Stability!Q4") var pingCap = pingCapCell.getValue(); if(!pingCap) { throw new Error("Ping Cap cell is empty (Channel Stability)."); } var dd = Utilities.formatDate(new Date(), timezone, "MM/dd/yyyy HH:mm"); var res = [dd] for(var i = 0; i < channelIps2[world].length; i++) { ip = "http://" + channelIps2[world][i] + ":8585?timestamp=" + Date.now(); ping = testPing(ip); console.log("Channel " + i + " ping: " + ping + "ms"); if(typeof ping == 'number' && ping > pingCap) { ping = "Capped"; } res.push(ping); Utilities.sleep(1500); //1.5s } var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PingTracking"); var lastRow = sheet.getRange("B" + (sheet.getLastRow() + 1)) var upRow = lastRow.getNextDataCell(SpreadsheetApp.Direction.UP).getRow() var row = Math.max(upRow, 2); sheet.getRange(row+1, 2, 1, channelIps2[world].length + 1).setValues([res]); } function legionPlanning() { startLegionTracking(); var legionSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Legion Tracker"); var legionIgnCells = legionSheet.getRange("Legion Tracker!C7:C45"); var legionIgns = legionIgnCells.getDisplayValues(); var legionLevels = []; for(var i = 0; i < legionIgns.length; i++) { var ign = legionIgns[i][0]; if(ign != '') { var rankingUrl = "https://maplestory.nexon.net/api/ranking?id=overall&id2=legendary&rebootIndex=0&character_name=" + ign + "&page_index=1"; var rankingContent = UrlFetchApp.fetch(rankingUrl).getContentText(); var rankJson = JSON.parse(rankingContent)[0]; var level = rankJson.Level; legionLevels.push([level]); } else { legionLevels.push(['']); } } legionSheet.getRange(7, 6, legionLevels.length, 1).setValues(legionLevels); } function testPing(ip) { start = Date.now(); try { var ch = UrlFetchApp.fetch(ip); } catch (e) { if(e.message.includes("Unexpected error")) { return(Date.now() - start); } else { return(""); } } return(Date.now() - start); } function startPingTracking() { var triggers = ScriptApp.getProjectTriggers().filter(function(s) {return s.getHandlerFunction() === "channelScheduler"}); if(triggers.length == 0) { ScriptApp.newTrigger('channelScheduler').timeBased().everyHours(1).create(); } } function startCharTracking() { var triggers = ScriptApp.getProjectTriggers().filter(function(s) {return s.getHandlerFunction() === "characterScheduler"}); if(triggers.length == 0) { ScriptApp.newTrigger('characterScheduler').timeBased().everyHours(1).create(); } } function startLegionTracking() { var triggers = ScriptApp.getProjectTriggers().filter(function(s) {return s.getHandlerFunction() === "legionPlanning"}); if(triggers.length == 0) { ScriptApp.newTrigger('legionPlanning').timeBased().everyHours(1).create(); } } function scheduler() { startCharTracking(); startPingTracking(); startLegionTracking(); legionPlanning(); characterTracking(); channelStatus(); } function updateSheet() { cancelTriggers(); scheduler(); } function cancelTriggers() { var triggers = ScriptApp.getProjectTriggers(); for(var i = 0; i < triggers.length; i++) { ScriptApp.deleteTrigger(triggers[i]); } } function resetCharData() { var sheet = SpreadsheetApp.getActive().getSheetByName("EXPTracking"); var row = sheet.getLastRow() + 1; sheet.getRange('A2:Q' + row).clearContent(); } function resetPingData() { var sheet = SpreadsheetApp.getActive().getSheetByName("PingTracking"); var row = sheet.getLastRow() sheet.getRange('B3:AF' + row).clearContent(); } function importData() { resetCharData(); resetPingData(); var importSheet = SpreadsheetApp.getActive().getSheetByName("Import & Export"); var importModeCell = importSheet.getRange("Import & Export!G16"); var importMode = importModeCell.getValue(); var importDataSheet = SpreadsheetApp.getActive().getSheetByName("IMPORTEDDATA"); var importDataFlag1Cell = importDataSheet.getRange("IMPORTEDDATA!E1"); var importDataFlag2Cell = importDataSheet.getRange("IMPORTEDDATA!P1"); var importDataFlag1 = importDataFlag1Cell.getValue(); var importDataFlag2 = importDataFlag2Cell.getValue(); if(!importMode) { throw new Error("Import mode is not on."); return; } if(!importDataFlag1 || !importDataFlag2) { throw new Error("Data is not ready for import. Try again later."); return; } var row = importDataSheet.getLastRow(); var charSheet = SpreadsheetApp.getActive().getSheetByName("EXPTracking"); var pingSheet = SpreadsheetApp.getActive().getSheetByName("PingTracking"); var charData = importDataSheet.getRange("IMPORTEDDATA!A3:Q" + row).getDisplayValues(); var pingData = importDataSheet.getRange("IMPORTEDDATA!Y3:BC" + row).getDisplayValues(); charSheet.getRange(2, 1, charData.length, 17).setValues(charData); pingSheet.getRange(3, 2, pingData.length, 31).setValues(pingData); importModeCell.setValue(false); } function gatherInitialPingData(){ for(var i = 0; i < 5; i++) { channelStatus(); Utilities.sleep(15*1000); //45 seconds to run, 15 seconds sleep so we dont get throttled //Utilities.sleep(300000); //Cannot sleep for more than 5 minutes; } }