channel-statistics.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. registerPlugin({
  2. name: 'Client Statistics Script',
  3. version: '1.0',
  4. description: 'log client events to db',
  5. author: 'mcj201',
  6. vars: [
  7. {
  8. name: 'host',
  9. title: 'MySQL Host',
  10. type: 'string'
  11. },
  12. {
  13. name: 'username',
  14. title: 'MySQL User',
  15. type: 'string'
  16. },
  17. {
  18. name: 'password',
  19. title: 'MySQL Password',
  20. type: 'password'
  21. },
  22. {
  23. name: 'database',
  24. title: 'MySQL Database',
  25. type: 'string'
  26. },
  27. ],
  28. autorun: false,
  29. requiredModules: [
  30. 'db'
  31. ]
  32. }, function(sinusbot, config, meta) {
  33. const db = require('db');
  34. const engine = require('engine');
  35. const backend = require('backend');
  36. const event = require('event');
  37. const helpers = require('helpers');
  38. let dbc = null;
  39. function reconnect() {
  40. if(!dbc) {
  41. dbc = db.connect({ driver: 'mysql', host: config.host, username: config.username, password: config.password, database: config.database }, function(err) {
  42. if (err) {
  43. engine.log(err);
  44. } else {
  45. engine.log('connection successful');
  46. }
  47. });
  48. }
  49. }
  50. function remove_non_utf8(str) {
  51. if ((str === null) || (str === ''))
  52. return "";
  53. else
  54. str = str.toString();
  55. return str.replace(/[^\w\s\[\]\-:.\/!\?\(\)äáöüéôûµÄÁÖÜß=#<>\+\*\'\\`,\"“„€&%@§~^°|;]/g, '');
  56. }
  57. reconnect();
  58. setInterval(reconnect, 1000 * 3600);
  59. let channelIdMap = {};
  60. let serverId = null;
  61. event.on('connect', () => {
  62. const serverinfo = backend.extended().getServerInfo();
  63. updateServer(serverinfo, function(id) {
  64. serverId = id;
  65. engine.log('serverId: ' + serverId);
  66. backend.getChannels().forEach(channel => updateChannel(serverId, channel, function(id) {
  67. channelIdMap[channel.id()] = id;
  68. updateChannelEvent(id, channel);
  69. }));
  70. });
  71. });
  72. event.on('clientMove', ({ client, fromChannel, toChannel }) => {
  73. if(fromChannel) updateChannelEvent(channelIdMap[fromChannel.id()], fromChannel);
  74. if(toChannel) updateChannelEvent(channelIdMap[toChannel.id()], toChannel);
  75. });
  76. event.on('channelCreate', (channel, client) => {
  77. updateChannel(serverId, channel, function(id) {
  78. channelIdMap[channel.id()] = id;
  79. updateChannelEvent(id, channel);
  80. });
  81. });
  82. event.on('channelUpdate', (channel, client) => {
  83. updateChannel(serverId, channel, function(id) {
  84. channelIdMap[channel.id()] = id;
  85. updateChannelEvent(id, channel);
  86. });
  87. });
  88. function updateServer(serverinfo, cb) {
  89. if(!dbc || !serverinfo) {
  90. engine.log('error on server update');
  91. return;
  92. }
  93. dbc.query("SELECT id, name FROM server WHERE uid = ?", serverinfo.UID(), function(err, res) {
  94. if (!err) {
  95. if(res.length > 0) {
  96. const serverId = res[0].id;
  97. dbc.exec("UPDATE server SET name = ? WHERE id = ?", serverinfo.name(), serverId);
  98. cb(serverId);
  99. } else {
  100. dbc.exec("INSERT INTO server (uid, name) VALUES (?, ?)", serverinfo.UID(), serverinfo.name(), function() {
  101. dbc.query("SELECT id FROM server WHERE uid = ?", serverinfo.UID(), function(err, res) {
  102. if(!err && res.length > 0) {
  103. cb(res[0].id);
  104. } else {
  105. engine.log(err, res);
  106. }
  107. });
  108. });
  109. }
  110. } else {
  111. engine.log(err, res);
  112. }
  113. });
  114. }
  115. function updateChannel(serverId, channel, cb) {
  116. if(!dbc || !serverId) {
  117. return;
  118. }
  119. const parentId = channel.parent() ? channel.parent().id() : NaN;
  120. dbc.query("SELECT * FROM channel WHERE channelId = ? AND serverId = ?", channel.id(), serverId, function(err, res) {
  121. if (!err) {
  122. if(res.length > 0) {
  123. const id = res[0].id;
  124. dbc.exec("UPDATE channel SET name = ?, parentId = ?, position = ?, description = ? WHERE channelId = ? AND serverId = ?",
  125. remove_non_utf8(channel.name()), parentId, channel.position(), remove_non_utf8(channel.description()), channel.id(), serverId);
  126. cb(id);
  127. } else {
  128. dbc.exec("INSERT INTO channel (channelId, name, serverId, parentId, position, description) VALUES (?, ?, ?, ?, ?, ?)",
  129. channel.id(), remove_non_utf8(channel.name()), serverId, parentId, channel.position(), remove_non_utf8(channel.description()), function() {
  130. dbc.query("SELECT id FROM channel WHERE channelId = ? AND serverId = ?", channel.id(), serverId, function(err, res) {
  131. if(!err && res.length > 0) {
  132. cb(res[0].id);
  133. } else {
  134. engine.log(err, res);
  135. }
  136. });
  137. });
  138. }
  139. } else {
  140. engine.log(err, res);
  141. }
  142. });
  143. }
  144. function updateChannelEvent(id, channel) {
  145. if(!dbc || !id) {
  146. return;
  147. }
  148. const clients = channel.getClientCount();
  149. dbc.query("SELECT * FROM channelEvent WHERE channelId = ? AND date > DATE_SUB(NOW(), INTERVAL 1 MINUTE) ORDER BY date DESC LIMIT 1", id, function(err, res) {
  150. if(!err) {
  151. if(res.length > 0) {
  152. engine.log('channel ' + remove_non_utf8(channel.name()) + ' updated to ' + clients + ' clients');
  153. dbc.exec("UPDATE channelEvent SET clientCount = ? WHERE id = ?", clients, res[0].id);
  154. } else {
  155. dbc.query("SELECT * FROM channelEvent WHERE channelId = ? ORDER BY date DESC LIMIT 1", id, function(err, res) {
  156. if(!err && res.length > 0 && res[0].clientCount === clients)
  157. return;
  158. if(clients > 0)
  159. engine.log('channel ' + remove_non_utf8(channel.name()) + ' has now ' + clients + ' clients');
  160. dbc.exec("INSERT INTO channelEvent (channelId, clientCount) VALUES (?, ?)", id, clients);
  161. });
  162. }
  163. } else {
  164. engine.log(err, res);
  165. }
  166. });
  167. }
  168. });