Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
1 let imageData;
2 let enemiesData;
3 let oldEnemies = []
4 let updatedEnemies = [];
5
6 async function init() {
7 const dbResponse = await fetch('https://flatmmo.wiki/custom/proxyImages.php?url=https://flatmmo.com/db/', {
8 method: 'GET',
9 });
10
11 imageData = await dbResponse.text();
12
13 //This data comes from the game server
14 const monstersResponse = await fetch('https://flatmmo.com/data/monsters.json', {
15 method: 'GET',
16 headers: {
17 'Content-Type': 'application/json',
18 },
19 });
20 enemiesData = await monstersResponse.json();
21
22 //Fetch the enemy list from Module:Enemies_DB
23 const oldEnemiesResponse = await fetch('https://flatmmo.wiki/index.php/Module:Enemies_DB?action=raw', {
24 method: 'GET',
25 headers: {
26 'Content-Type': 'application/json',
27 },
28 });
29 const luaString = await oldEnemiesResponse.text();
30
31 //Turn it from a Lua table to a js array
32 oldEnemies = JSON.parse(luaString.replace(/(.|[\r\n])*?return {/,"[") //Remove the return {
33 .replaceAll("{","[")
34 .replaceAll("}","]"));
35
36 const dbDiv = document.getElementById("enemiesDB");
37 const fetchBtn = document.createElement("button");
38 fetchBtn.innerText = "Fetch and Update";
39 fetchBtn.addEventListener("click", ()=> {updateEnemyDB()});
40 dbDiv.appendChild(fetchBtn);
41 }
42
43 async function updateEnemyDB() {
44 enemiesData.forEach((enemy, index) => {
45 const enemyInfo = [enemy.name, "Others", enemy.max_hit, enemy.accuracy, enemy.defence, enemy.magic_defence, enemy.hp, enemy.weakness, []]
46 if(enemy.collection_log === "boss") {
47 enemyInfo.push(true)
48 }
49 enemy.drops.forEach((drop, i) => {
50 enemyInfo[8][i] = [drop.item, drop.min, drop.max, drop.chance + 1]
51 if(drop.unique) {
52 enemyInfo[8][i].push(true)
53 }
54 })
55 updatedEnemies[index] = enemyInfo
56 })
57
58 //Add info that is not auto generated
59 oldEnemies.forEach(enemy => {
60 try {
61 const newIndex = updatedEnemies.findIndex(e => e[0] === enemy[0])
62 updatedEnemies[newIndex][1] = enemy[1]; //This is the area
63 if(enemy[10]) {
64 updatedEnemies[newIndex][9] = enemy[9] || false; //In case it doesn't have it already
65 updatedEnemies[newIndex][10] = enemy[10]; //This is the custom image path
66 }
67 } catch(error) {
68 console.log(enemy)
69 }
70 })
71
72
73 const luaEnemies = `-- Format: {Name, Area, Damage, Accuracy, Defence, Magic Defence, HP, Weakness, {Loot1,Loot2}, Is Boss(optional), Image Path(optional)}
74 -- Drop Format: {Name, Min, Max, Chance, Unique (optional)}
75 return ` + JSON.stringify(updatedEnemies).replaceAll("[","{")
76 .replaceAll("]","}") //Turn [] into {}
77 .replaceAll(/}}(.*?)},{"/g, `}}$1},\n{"`); //Adds new lines between each enemy, just to make it easier to edit the file
78
79 await postWithAPI("Module:Enemies_DB", luaEnemies)
80 updateEnemiesNavbox()
81 document.getElementById("enemiesDBStatus").innerText = "UPDATED";
82 }
83
84 async function updateEnemiesNavbox() {
85 const areas = {};
86 let enemiesNavbox =`{| class="wikitable mw-collapsible mw-collapsed enemiesNavbox" style="width:100%"
87 ! colspan="2"| [[File:Silkfang.png|25px|link=]] [[Enemies]] [[File:Silkfang.png|25px|link=]]`
88 updatedEnemies.forEach(enemy => {
89 const area = enemy[1] || "Others";
90 if(!areas.hasOwnProperty(area)) {
91 areas[area] = [];
92 }
93 areas[area].push(enemy);
94 })
95 for(area in areas) {
96 enemiesNavbox += `\n|-\n!${area}\n|`
97 areas[area].forEach((enemy, index) => {
98 enemiesNavbox += `[[File:${[enemy[0]]}.png|25px|link=${titleCase(enemy[0])}]] [[${titleCase(enemy[0])}]]`
99 if(index + 1 !== areas[area].length) {
100 enemiesNavbox += " • "
101 }
102 })
103 }
104 enemiesNavbox += "\n|}";
105 postWithAPI("Template:Navbox_Enemies", enemiesNavbox);
106
107 updateImages();
108 }
109
110 async function postWithAPI(title, Content) {
111 const api = new mw.Api();
112 const params = {
113 action: 'edit',
114 title: title,
115 text: Content,
116 summary: "Updated using game files via API",
117 format: "json"
118 };
119
120 api.postWithToken( 'csrf', params ).done( function ( data ) {
121 console.log( data );
122 } );
123 }
124
125 async function updateImages() {
126 const api = new mw.Api();
127 let images = [];
128
129 const items = imageData.matchAll(/src="..\/images(.*?).png/g);
130
131 items.forEach(item => {
132 obj = {}
133 const file = item[1].match(/.*\/(.*)$/);
134 obj.file = file[1].replaceAll("_stand1", "") + ".png";
135 obj.path = "https://flatmmo.com/images" + item[1] + ".png"
136 images.push(obj)
137 })
138
139 images.forEach(image => {
140 const params = {
141 action: 'upload',
142 filename: image.file,
143 url: image.path,
144 ignorewarnings: '1',
145 format: 'json'
146 }
147 api.postWithToken( 'csrf', params ).done( function ( data ) {
148 console.log( data );
149 } );
150 })
151 }
152
153 const titleCase = (s) => {
154 return s.replace (/^[-_]*(.)/, (_, c) => c.toUpperCase())
155 .replace (/[-_]+(.)/g, (_, c) => ' ' + c.toUpperCase())
156 }
157 init()
