Advertisement
Guest User

Nodejs Anope Database Merger

a guest
Apr 3rd, 2019
381
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //This requires Node.js to run. Please put this in a file and run "node filename"
  2. //It was created to merge old backups of anope.db-date files located in the same directory as this script.
  3. //It will go from the last back up to the earliest.
  4.  
  5. 'use strict'
  6.  
  7. //BACKUP ALL CURRENT DATABASE FILES BEFORE REPLACING WITH THE OUTPUT OF THIS SCRIPT!
  8. //Made by Colten Covington / Colten45
  9. //You may contact me via colten.covington@gmail.com or colten at tmro.tv if you need help
  10. //or come to any chat related to TMRO.tv and I am usually around those.
  11.  
  12. //Set each type to false or true depending on what you want to merge.
  13. //All set to true with seeninfoMergeALL set to false is a full merge.
  14. let types = {
  15.     'BotInfo': true,
  16.     'Stats': true,
  17.     'NickCore': true,
  18.     'NickAlias': true,
  19.     'ChannelInfo': true,
  20.     'ChanAccess': true,
  21.     'ModeLock': true,
  22.     'SeenInfo': true,
  23.     'AJoinEntry': true,
  24.     'NSMiscData': true,
  25.     'Exception': true
  26. }
  27. //seeninfoMergeALL set to false will only merge seeninfo of users who are registered and on the very first db file.
  28. //seeninfoMergeALL set to true will merge all seeninfo WARNING this can be quite big if done on a large set of database backups.
  29. let seeninfoMergeALL = false;
  30.  
  31.  
  32. //Only known thing to me currently is stats are duplicated due to below code using the last param of the first DATA line for an OBJECT
  33.  
  34. //I had one bug in an old db that was a NSMiscDataUSERNAME OBJECT So the types object above is checked to make sure corrupted data is not brought over.
  35.  
  36. const path = require('path');
  37. const fs = require('fs');
  38. const directoryPath = path.join(__dirname);
  39. let objects = [];
  40. let objectnames = {};
  41. let objectnamescaseins = {};
  42. let dontadd = [];
  43. let nickcore = '';
  44. let i = 0;
  45. let stats = true;
  46. fs.readdir(directoryPath, function (err, files) {
  47.     if (err) {
  48.         return console.log('Unable to scan directory: ' + err);
  49.     }
  50.     files = files.reverse()
  51.     files.forEach(function (file) {
  52.         if (file.indexOf('anope') == 0) {
  53.             i++;
  54.             var contents = fs.readFileSync(file, 'utf8');
  55.             let blam = contents.trim().split('END').slice(0,-1);
  56.             blam.forEach(function (object) {
  57.                 objects.push(object);
  58.                 object = object.trim().split('\n').splice(0,object.trim().split('\n').length);
  59.                 let data = object.splice(1);
  60.                 if (data.length != 0 && types[object[0].split(' ')[1]]) {
  61.                     if (object[0].split(' ')[1] == 'Stats' && stats) {
  62.                         if (!objectnames[object[0].split(' ')[1]]) {
  63.                             objectnames[object[0].split(' ')[1]] = {objectCount:0};
  64.                             objectnamescaseins[object[0].split(' ')[1]] = {objectCount:0};
  65.                         }
  66.                         if (!objectnamescaseins[object[0].split(' ')[1]][(['ChanAccess','ModeLock'].indexOf(object[0].split(' ')[1]) != -1) ? data[2].split(' ')[data[2].split(' ').length - 1].toLowerCase() : data[0].split(' ')[data[0].split(' ').length - 1].toLowerCase()] && dontadd.indexOf(data[0].split(' ')[data[0].split(' ').length - 1]) == -1) {
  67.                             objectnames[object[0].split(' ')[1]][(['ChanAccess','ModeLock'].indexOf(object[0].split(' ')[1]) != -1) ? data[2].split(' ')[data[2].split(' ').length - 1] : data[0].split(' ')[data[0].split(' ').length - 1]] = {firstFile:i};
  68.                             objectnamescaseins[object[0].split(' ')[1]][(['ChanAccess','ModeLock'].indexOf(object[0].split(' ')[1]) != -1) ? data[2].split(' ')[data[2].split(' ').length - 1].toLowerCase() : data[0].split(' ')[data[0].split(' ').length - 1].toLowerCase()] = {};
  69.                             data.forEach(function (d) {
  70.                                 let type = objectnames[object[0].split(' ')[1]][(['ChanAccess','ModeLock'].indexOf(object[0].split(' ')[1]) != -1) ? data[2].split(' ')[data[2].split(' ').length - 1] : data[0].split(' ')[data[0].split(' ').length - 1]];
  71.                                 type[d.split(' ')[1]] = d.split(' ').slice(2)[0] == '' ? d.split(' ').slice(2).join(' '): d.split(' ').slice(2).join(' ');
  72.                             })
  73.                         }
  74.                         objectnames[object[0].split(' ')[1]].objectCount++;
  75.                         stats = false;
  76.                     }
  77.                     else if (object[0].split(' ')[1] != 'Stats') {
  78.                         if (!objectnames[object[0].split(' ')[1]]) {
  79.                             objectnames[object[0].split(' ')[1]] = {objectCount:0};
  80.                             objectnamescaseins[object[0].split(' ')[1]] = {objectCount:0};
  81.                         }
  82.                         if (!objectnamescaseins[object[0].split(' ')[1]][(['ChanAccess','ModeLock'].indexOf(object[0].split(' ')[1]) != -1) ? data[2].split(' ')[data[2].split(' ').length - 1].toLowerCase() : data[0].split(' ')[data[0].split(' ').length - 1].toLowerCase()] && dontadd.indexOf(data[0].split(' ')[data[0].split(' ').length - 1]) == -1) {
  83.                             objectnames[object[0].split(' ')[1]][(['ChanAccess','ModeLock'].indexOf(object[0].split(' ')[1]) != -1) ? data[2].split(' ')[data[2].split(' ').length - 1] : data[0].split(' ')[data[0].split(' ').length - 1]] = {firstFile:i};
  84.                             objectnamescaseins[object[0].split(' ')[1]][(['ChanAccess','ModeLock'].indexOf(object[0].split(' ')[1]) != -1) ? data[2].split(' ')[data[2].split(' ').length - 1].toLowerCase() : data[0].split(' ')[data[0].split(' ').length - 1].toLowerCase()] = {};
  85.                             data.forEach(function (d) {
  86.                                 let type = objectnames[object[0].split(' ')[1]][(['ChanAccess','ModeLock'].indexOf(object[0].split(' ')[1]) != -1) ? data[2].split(' ')[data[2].split(' ').length - 1] : data[0].split(' ')[data[0].split(' ').length - 1]];
  87.                                 type[d.split(' ')[1]] = d.split(' ').slice(2)[0] == '' ? d.split(' ').slice(2).join(' '): d.split(' ').slice(2).join(' ');
  88.                             })
  89.                         }
  90.                         objectnames[object[0].split(' ')[1]].objectCount++;
  91.                     }
  92.                 }
  93.             })
  94.         }
  95.     });
  96.    
  97.     for (var objectType in objectnames) {
  98.         if (types[objectType]) {
  99.             for (var property in objectnames[objectType]) {
  100.                 if (objectnames[objectType].hasOwnProperty(property) && property != "objectCount") {
  101.                     if (!seeninfoMergeALL && objectType == 'SeenInfo') {
  102.                         if (objectnames.NickCore[property] || objectnames[objectType][property].firstFile == 1) {
  103.                             nickcore += 'OBJECT ' + objectType + '\u000a';
  104.                             let datatype = '';
  105.                             for (var type in objectnames[objectType][property]) {
  106.                                 if (objectnames[objectType].hasOwnProperty(property) && type != "firstFile") {
  107.                                     datatype += 'DATA ' + type + ' ' + objectnames[objectType][property][type] + '\u000a';
  108.                                 }
  109.                             }
  110.                             nickcore += datatype;
  111.                             nickcore += 'END\u000a';
  112.                         }
  113.                     }
  114.                     else {
  115.                         nickcore += 'OBJECT ' + objectType + '\u000a';
  116.                         let datatype = '';
  117.                         for (var type in objectnames[objectType][property]) {
  118.                             if (objectnames[objectType].hasOwnProperty(property) && type != "firstFile") {
  119.                                 datatype += 'DATA ' + type + ' ' + objectnames[objectType][property][type] + '\u000a';
  120.                             }
  121.                         }
  122.                         nickcore += datatype;
  123.                         nickcore += 'END\u000a';
  124.                     }
  125.                 }
  126.             }
  127.         }
  128.     }
  129.     fs.writeFileSync('new.db', nickcore);
  130.     console.log('Done')
  131. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement