您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows PvP/PvE Ranking of the players alliance in the PlayerWindow, also adds POIs the Player holds and splits pve/pvp score.
// ==UserScript== // @name C&C Tiberium Alliances PvP/PvE Ranking, POI Holding and split base kill score. // @author ViolentVin, KRS_L, YiannisS // @description Shows PvP/PvE Ranking of the players alliance in the PlayerWindow, also adds POIs the Player holds and splits pve/pvp score. // @namespace pvp_rank_mod // @include https://prodgame*.alliances.commandandconquer.com/*/index.aspx* // @grant none // @version 1.7.3 // ==/UserScript== (function () { var PvpRankMod_main = function () { var allianceId = null; var allianceName = null; var button = null; var general = null; var memberCount = null; var playerInfoWindow = null; var playerName = null; var pvpHighScoreLabel = null; var poiTableLabel = null; var rowData = null; var tabView = null; var pData = null; var dataTable = null; var pvpScoreLabel = null; var pveScoreLabel = null; var Bname = null; var Olv = null; var Dlv = null; var Blv = null; var Slv = null; var Cylev = null; var Dflev = null; var tableModel = null; var atableModel = null; var levelData = null; var baseCoords = null; var rowData1 = null; var pois = null; var rowData2 = []; function CreateMod() { try { console.log('PvP/PvE Ranking Mod + POI + Base Levels Loaded.'); var tr = qx.locale.Manager.tr; playerInfoWindow = webfrontend.gui.info.PlayerInfoWindow.getInstance(); if (PerforceChangelist >= 436669) { // 15.3 patch var eventType = "cellTap"; general = playerInfoWindow.getChildren()[0].getChildren()[0].getChildren()[0].getChildren()[0].getChildren()[0].getChildren()[0].getChildren()[1].getChildren()[0]; } else { //old var eventType = "cellClick"; general = playerInfoWindow.getChildren()[0].getChildren()[0].getChildren()[0].getChildren()[0].getChildren()[0].getChildren()[1].getChildren()[0]; } tabView = playerInfoWindow.getChildren()[0]; playerName = general.getChildren()[1]; allianceName = ClientLib.Data.MainData.GetInstance().get_Alliance().get_Name(); // New PvP Ranking Tab-page var pvpRankingTab = new qx.ui.tabview.Page("Ranking"); pvpRankingTab.setLayout(new qx.ui.layout.Canvas()); pvpRankingTab.setPaddingTop(6); pvpRankingTab.setPaddingLeft(8); pvpRankingTab.setPaddingRight(10); pvpRankingTab.setPaddingBottom(8); // Label PvP Ranking pvpHighScoreLabel = new qx.ui.basic.Label("PvP and PvE for Alliance: ").set({ textColor: "text-value", font: "font_size_13_bold" }); pvpRankingTab.add(pvpHighScoreLabel); // Table to show the PvP Scores of each player dataTable = new webfrontend.data.SimpleColFormattingDataModel().set({ caseSensitiveSorting: false }); dataTable.setColumns(["Name", "PvP", "PvE"], ["name", "pve", "pvp"]); dataTable.setColFormat(0, "<div style=\"cursor:pointer;color:" + webfrontend.gui.util.BBCode.clrLink + "\">", "</div>"); var pvpTable = new webfrontend.gui.widgets.CustomTable(dataTable); pvpTable.addListener("eventType", playerInfo, this); var columnModel = pvpTable.getTableColumnModel(); columnModel.setColumnWidth(0, 200); columnModel.setColumnWidth(1, 80); columnModel.setColumnWidth(2, 80); columnModel.setDataCellRenderer(0, new qx.ui.table.cellrenderer.Html()); pvpTable.setStatusBarVisible(false); pvpTable.setColumnVisibilityButtonVisible(false); pvpRankingTab.add(pvpTable, { left: 0, top: 25, right: 0, bottom: 0 }); // Add Tab page to the PlayerInfoWindow tabView.add(pvpRankingTab); // POI Tab var poiTab = new qx.ui.tabview.Page("POI"); poiTab.setLayout(new qx.ui.layout.Canvas()); poiTab.setPaddingTop(6); poiTab.setPaddingLeft(8); poiTab.setPaddingRight(10); poiTab.setPaddingBottom(8); poiTableLabel = new qx.ui.basic.Label("Player sits on these POIs").set({ textColor: "text-value", font: "font_size_13_bold" }); poiTab.add(poiTableLabel); tableModel = new webfrontend.data.SimpleColFormattingDataModel().set({ caseSensitiveSorting: false }); tableModel.setColumns([tr("POI Type"), tr("Level"), tr("Score"), tr("Coordinates"), tr("Base Name")], ["t", "l", "s", "c", "basen"]); tableModel.setColFormat(3, "<div style=\"cursor:pointer;color:" + webfrontend.gui.util.BBCode.clrLink + "\">", "</div>"); var poiTable = new webfrontend.gui.widgets.CustomTable(tableModel); //poiTable.addListener("eventType", centerCoords, this); var columnModel = poiTable.getTableColumnModel(); columnModel.setColumnWidth(0, 190); columnModel.setColumnWidth(1, 45); columnModel.setColumnWidth(2, 80); columnModel.setColumnWidth(3, 80); columnModel.setColumnWidth(4, 200); columnModel.setDataCellRenderer(3, new qx.ui.table.cellrenderer.Html()); //columnModel.getDataCellRenderer(1).setUseAutoAlign(true); columnModel.getDataCellRenderer(2).setUseAutoAlign(false); poiTable.setStatusBarVisible(false); poiTable.setColumnVisibilityButtonVisible(true); poiTab.add(poiTable, { left: 0, top: 25, right: 0, bottom: 0 }); tabView.add(poiTab); // Alliance POIs Tab var apoiTab = new qx.ui.tabview.Page("Alliance POIs"); apoiTab.setLayout(new qx.ui.layout.Canvas()); apoiTab.setPaddingTop(6); apoiTab.setPaddingLeft(8); apoiTab.setPaddingRight(10); apoiTab.setPaddingBottom(8); var apoiTableLabel = new qx.ui.basic.Label("Alliance members are holding the following POIs").set({ textColor: "text-value", font: "font_size_13_bold" }); apoiTab.add(apoiTableLabel); atableModel = new webfrontend.data.SimpleColFormattingDataModel().set({ caseSensitiveSorting: false }); atableModel.setColumns([tr("POI Type"), tr("Level"), tr("Score"), tr("Coordinates"), tr("Player Name"), tr("Base Name")], ["t", "l", "s", "c", "p", "basen"]); atableModel.setColFormat(3, "<div style=\"cursor:pointer;color:" + webfrontend.gui.util.BBCode.clrLink + "\">", "</div>"); atableModel.setColFormat(4, "<div style=\"cursor:pointer;color:" + webfrontend.gui.util.BBCode.clrLink + "\">", "</div>"); var apoiTable = new webfrontend.gui.widgets.CustomTable(atableModel); //apoiTable.addListener("eventType", centerCoords, this); var columnModel = apoiTable.getTableColumnModel(); columnModel.setColumnWidth(0, 190); columnModel.setColumnWidth(1, 45); columnModel.setColumnWidth(2, 80); columnModel.setColumnWidth(3, 80); columnModel.setColumnWidth(4, 130); columnModel.setColumnWidth(5, 115); columnModel.getDataCellRenderer(2).setUseAutoAlign(false); columnModel.setDataCellRenderer(3, new qx.ui.table.cellrenderer.Html()); columnModel.setDataCellRenderer(4, new qx.ui.table.cellrenderer.Html()); apoiTable.setStatusBarVisible(false); apoiTable.setColumnVisibilityButtonVisible(true); apoiTab.add(apoiTable, { left: 0, top: 25, right: 0, bottom: 5 }); tabView.add(apoiTab); // Levels Tab var levelTab = new qx.ui.tabview.Page("Base Levels"); levelTab.setLayout(new qx.ui.layout.Canvas()); levelTab.setPaddingTop(6); levelTab.setPaddingLeft(8); levelTab.setPaddingRight(10); levelTab.setPaddingBottom(8); levelData = new webfrontend.data.SimpleColFormattingDataModel().set({ caseSensitiveSorting: false }); levelData.setColumns(["Name", "Lvl", "DL", "OL", "SW", "CY", "DF"], ["Bname", "Blv", "Dlv", "Olv", "Slv", "Cylev", "Dflev"]); levelData.setColFormat(0, "<div style=\"cursor:pointer;color:" + webfrontend.gui.util.BBCode.clrLink + "\">", "</div>"); var levelTable = new webfrontend.gui.widgets.CustomTable(levelData); levelTable.addListener("eventType", centerCoords, this); var columnlModel = levelTable.getTableColumnModel(); columnlModel.setColumnWidth(0, 180); columnlModel.setColumnWidth(1, 70); columnlModel.setColumnWidth(2, 70); columnlModel.setColumnWidth(3, 70); columnlModel.setColumnWidth(4, 70); columnlModel.setColumnWidth(5, 70); columnlModel.setColumnWidth(6, 70); columnlModel.setDataCellRenderer(0, new qx.ui.table.cellrenderer.Html()); columnlModel.getDataCellRenderer(2).setUseAutoAlign(false); levelTable.setStatusBarVisible(false); levelTable.setColumnVisibilityButtonVisible(false); levelTab.add(levelTable, { left: 0, top: 0, right: 0, bottom: 0 }); tabView.add(levelTab); var pvpLabel = new qx.ui.basic.Label("- PvP:"); pvpScoreLabel = new qx.ui.basic.Label("").set({ textColor: "text-value", font: "font_size_13_bold" }); general.add(pvpLabel, { row: 3, column: 3 }); general.add(pvpScoreLabel, { row: 3, column: 4 }); var pveLabel = new qx.ui.basic.Label("- PvE:"); pveScoreLabel = new qx.ui.basic.Label("").set({ textColor: "text-value", font: "font_size_13_bold" }); general.add(pveLabel, { row: 4, column: 3 }); general.add(pveScoreLabel, { row: 4, column: 4 }); // Hook up callback when another user has been selected playerInfoWindow.addListener("close", onPlayerInfoWindowClose, this); playerName.addListener("changeValue", onPlayerChanged, this); } catch (e) { console.log("CreateMod: ", e); } } function playerInfo(e) { try { var pname = dataTable.getRowData(e.getRow())[0]; if (e.getColumn() == 0) { webfrontend.gui.util.BBCode.openPlayerProfile(pname); } } catch (e) { console.log("PlayerName: ", e); } } function centerCoords(e) { try { var poiCoord = tableModel.getRowData(e.getRow())[3].split(":"); if (e.getColumn() == 3) webfrontend.gui.UtilView.centerCoordinatesOnRegionViewWindow(Number(poiCoord[0]), Number(poiCoord[1])); } catch (e) { console.log("centerCoords: ", e); } } function baseinfos(e){ try { var Cylv = null; var Cylev = null; var Dflv = null; var Dflev = null; var Slev = null; var aC = ClientLib.Data.MainData.GetInstance().get_Cities().get_AllCities().d; //console.log("aC =", ClientLib.Data.Cities().get_Cities()); var pData = []; for (var sBID in aC) { if (!aC.hasOwnProperty(sBID)) { continue; } var sBase = aC[sBID]; if (sBase === undefined) { throw new Error('unable to find base: ' + sBID); } var unitlData = sBase.get_CityBuildingsData(); Cylv = unitlData.GetUniqueBuildingByTechName(ClientLib.Base.ETechName.Construction_Yard); Dflv = unitlData.GetUniqueBuildingByTechName(ClientLib.Base.ETechName.Defense_Facility); Slev = unitlData.GetUniqueBuildingByTechName(ClientLib.Base.ETechName.Support_Ion); if (Slev === null) Slev = unitlData.GetUniqueBuildingByTechName(ClientLib.Base.ETechName.Support_Art); if (Slev === null) Slev = unitlData.GetUniqueBuildingByTechName(ClientLib.Base.ETechName.Support_Air); if ( Cylv !== null) { Cylev = Cylv.get_CurrentLevel(); } if (Dflv !== null) { Dflev = Dflv.get_CurrentLevel(); } if (Slev !== null) { Slv = Slev.get_TechGameData_Obj().dn.slice(0, 3) + " : " + Slev.get_CurrentLevel(); } Bname = sBase.get_Name(); if (typeof Bname === 'string') { Bname.replace(/\./g, ''); } Blv = sBase.get_LvlBase(); Dlv = ('0' + sBase.get_LvlDefense().toFixed(2)).slice(-5); Olv = ('0' + sBase.get_LvlOffense().toFixed(2)).slice(-5); pData.push([Bname, Blv, Dlv, Olv, Slv, Cylev, Dflev]); } levelData.setData(pData); levelData.sortByColumn(3, false); } catch (e) { console.log("baseinfos: ", e); } } // Callback GetPublicPlayerInfoByName // [bde] => Forgotten Bases Destroyed // [d] => Player Bases Destroyed // [n] => Player Name function onPlayerInfoReceived(context, data) { try { var memberName = data.n; var pvp = data.d; var pve = data.bde; // Add player Base Levels. var tt = baseinfos(); var abases = data.c; var abaseCoords = new Object(); for (var i in abases) { var abase = abases[i]; abaseCoords[i] = new Object(); abaseCoords[i]["x"] = abase.x; abaseCoords[i]["y"] = abase.y; abaseCoords[i]["n"] = abase.n; } for (var k in pois) { var apoi = pois[k]; for (var j in abaseCoords) { var distanceX = Math.abs(abaseCoords[j].x - apoi.x); var distanceY = Math.abs(abaseCoords[j].y - apoi.y); if (distanceX > 2 || distanceY > 2) continue; if (distanceX == 2 && distanceY == 2) continue; var aname = phe.cnc.gui.util.Text.getPoiInfosByType(apoi.t).name; var alevel = apoi.l; var ascore = ClientLib.Base.PointOfInterestTypes.GetScoreByLevel(apoi.l); var acoords = phe.cnc.gui.util.Numbers.formatCoordinates(apoi.x, apoi.y); var abasen = abaseCoords[j].n; rowData2.push([aname, alevel, ascore, acoords, memberName, abasen]); break; } } // Add player with its PvP/PvE score. rowData.push([memberName, pvp, pve]); if (rowData.length == memberCount) { // Show Alliance name in label. pvpHighScoreLabel.setValue("PvP and PvE for Alliance: " + data.an); dataTable.setData(rowData); dataTable.sortByColumn(1, false); } } catch (e) { console.log("onPlayerInfoReceived: ", e); } } // GetPublicAllianceInfo Callback // [m] => Member Array // ( // [0] => Array // [n] => Name // ) // [mc] => Member Count function onAllianceInfoReceived(context, data) { try { rowData1 = []; pois = data.opois; for (var k in pois) { var poi = pois[k]; for (var j in baseCoords) { var distanceX = Math.abs(baseCoords[j].x - poi.x); var distanceY = Math.abs(baseCoords[j].y - poi.y); if (distanceX > 2 || distanceY > 2) continue; if (distanceX == 2 && distanceY == 2) continue; var name = phe.cnc.gui.util.Text.getPoiInfosByType(poi.t).name; var level = poi.l; var score = ClientLib.Base.PointOfInterestTypes.GetScoreByLevel(poi.l); var coords = phe.cnc.gui.util.Numbers.formatCoordinates(poi.x, poi.y); var basen = baseCoords[j].n; rowData1.push([name, level, score, coords, basen]); break; } } tableModel.setData(rowData1); tableModel.sortByColumn(0, true); // Clear rowData = []; dataTable.setData(rowData); var members = data.m; memberCount = data.mc; for (var i in members) { var member = members[i]; // For Each member (player); Get the PvP/PvE Score if (member.n.length > 0) { ClientLib.Net.CommunicationManager.GetInstance().SendSimpleCommand("GetPublicPlayerInfoByName", { name: member.n }, phe.cnc.Util.createEventDelegate(ClientLib.Net.CommandResult, this, onPlayerInfoReceived), null); } } atableModel.setData(rowData2); atableModel.sortByColumn(0, true); } catch (e) { console.log("onAllianceInfoReceived: ", e); } } function onPlayerAllianceIdReceived(context, data) { try { // No need to recreate the RankingPage when player is member of same alliance if (data.a != allianceId) { allianceId = data.a; // Show Alliance name in label. pvpHighScoreLabel.setValue("PvP and PvE for alliance: " + data.an + " (loading plz wait)"); // Get Alliance MembersList ClientLib.Net.CommunicationManager.GetInstance().SendSimpleCommand("GetPublicAllianceInfo", { id: allianceId }, phe.cnc.Util.createEventDelegate(ClientLib.Net.CommandResult, this, onAllianceInfoReceived), null); pvpScoreLabel.setValue((data.bd - data.bde).toString()); pveScoreLabel.setValue(data.bde.toString()); var bases = data.c; baseCoords = new Object(); for (var i in bases) { var base = bases[i]; baseCoords[i] = new Object(); baseCoords[i]["x"] = base.x; baseCoords[i]["y"] = base.y; baseCoords[i]["n"] = base.n; } rowData1 = []; var pois = data.opois; for (var k in pois) { var poi = pois[k]; for (var j in baseCoords) { var distanceX = Math.abs(baseCoords[j].x - poi.x); var distanceY = Math.abs(baseCoords[j].y - poi.y); if (distanceX > 2 || distanceY > 2) continue; if (distanceX == 2 && distanceY == 2) continue; var name = phe.cnc.gui.util.Text.getPoiInfosByType(poi.t).name; var level = poi.l; var score = ClientLib.Base.PointOfInterestTypes.GetScoreByLevel(poi.l); var coords = phe.cnc.gui.util.Numbers.formatCoordinates(poi.x, poi.y); var basen = baseCoords[j].n; rowData1.push([name, level, score, coords, basen]); break; } } tableModel.setData(rowData1); tableModel.sortByColumn(0, true); } else { pvpScoreLabel.setValue((data.bd - data.bde).toString()); pveScoreLabel.setValue(data.bde.toString()); var bases = data.c; baseCoords = new Object(); for (var i in bases) { var base = bases[i]; baseCoords[i] = new Object(); baseCoords[i]["x"] = base.x; baseCoords[i]["y"] = base.y; baseCoords[i]["n"] = base.n; } ClientLib.Net.CommunicationManager.GetInstance().SendSimpleCommand("GetPublicAllianceInfo", { id: data.a }, phe.cnc.Util.createEventDelegate(ClientLib.Net.CommandResult, this, onAllianceInfoReceived), null); rowData1 = []; var pois = data.opois; for (var k in pois) { var poi = pois[k]; for (var j in baseCoords) { var distanceX = Math.abs(baseCoords[j].x - poi.x); var distanceY = Math.abs(baseCoords[j].y - poi.y); if (distanceX > 2 || distanceY > 2) continue; if (distanceX == 2 && distanceY == 2) continue; var name = phe.cnc.gui.util.Text.getPoiInfosByType(poi.t).name; var level = poi.l; var score = ClientLib.Base.PointOfInterestTypes.GetScoreByLevel(poi.l); var coords = phe.cnc.gui.util.Numbers.formatCoordinates(poi.x, poi.y); var basen = baseCoords[j].n; rowData1.push([name, level, score, coords, basen]); break; } } tableModel.setData(rowData1); tableModel.sortByColumn(0, true); } } catch (e) { console.log("onPlayerAllianceIdReceived: ", e); } } function onPlayerChanged() { try { // Get Players AllianceId if (playerName.getValue().length > 0) { ClientLib.Net.CommunicationManager.GetInstance().SendSimpleCommand("GetPublicPlayerInfoByName", { name: playerName.getValue() }, phe.cnc.Util.createEventDelegate(ClientLib.Net.CommandResult, this, onPlayerAllianceIdReceived), null); } rowData2 = []; } catch (e) { console.log("onPlayerChanged: ", e); } } function onPlayerInfoWindowClose() { try { console.log("onPlayerinfoWindowClose"); pvpScoreLabel.setValue(""); pveScoreLabel.setValue(""); tableModel.setData([]); //dataTable.setData([]); } catch (e) { console.log("onPlayerInfoWindowClose: ", e); } } function PvpRankMod_checkIfLoaded() { try { if (typeof qx !== 'undefined' && typeof qx.locale !== 'undefined' && typeof qx.locale.Manager !== 'undefined') { if (ClientLib.Data.MainData.GetInstance().get_Alliance().get_FirstLeaders() !== null && ClientLib.Data.MainData.GetInstance().get_Alliance().get_FirstLeaders().l.length != 0) { CreateMod(); } else { window.setTimeout(PvpRankMod_checkIfLoaded, 1000); } } else { window.setTimeout(PvpRankMod_checkIfLoaded, 1000); } } catch (e) { console.log("PvpRankMod_checkIfLoaded: ", e); } } if (/commandandconquer\.com/i.test(document.domain)) { window.setTimeout(PvpRankMod_checkIfLoaded, 1000); } }; try { var PvpRankMod = document.createElement("script"); PvpRankMod.innerHTML = "(" + PvpRankMod_main.toString() + ")();"; PvpRankMod.type = "text/javascript"; if (/commandandconquer\.com/i.test(document.domain)) { document.getElementsByTagName("head")[0].appendChild(PvpRankMod); } } catch (e) { console.log("PvpRankMod: init error: ", e); } })();