server.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import restify from "restify";
  2. import _ from "lodash";
  3. import loadDb from "./db.js";
  4. import corsMiddleware from "cors";
  5. import { errors } from "common";
  6. const factions = [
  7. { name: "Arborec", id: 1 },
  8. { name: "Barony of Letnev", id: 2 },
  9. { name: "Clan of Saar", id: 3 },
  10. { name: "Embers of Muaat", id: 4 },
  11. { name: "Emirates of Hacan", id: 5 },
  12. { name: "Federation of Sol", id: 6 },
  13. { name: "Ghosts of Creuss", id: 7 },
  14. { name: "L1Z1X Mindnet", id: 8 },
  15. { name: "Mentak Coalition", id: 9 },
  16. { name: "Naalu Collective", id: 10 },
  17. { name: "Nekro Virus", id: 11 },
  18. { name: "Sardakk N’orr", id: 12 },
  19. { name: "Universities of Jol-Nar", id: 13 },
  20. { name: "Winnu", id: 14 },
  21. { name: "Xxcha Kingdom", id: 15 },
  22. { name: "Yin Brotherhood", id: 16 },
  23. { name: "Yssaril Tribes", id: 17 },
  24. { name: "Argent Flight", id: 18 },
  25. { name: "Empyrean", id: 19 },
  26. { name: "Mahact Gene-Sorcerers", id: 20 },
  27. { name: "Naaz-Rokha Alliance", id: 21 },
  28. { name: "Nomad", id: 22 },
  29. { name: "Titans of Ul", id: 23 },
  30. { name: "Vuil'Raith Cabal", id: 24 }
  31. ];
  32. const db = loadDb("./data/ti.db");
  33. const server = restify.createServer({
  34. name: "spoll",
  35. version: "1.0.1"
  36. });
  37. server.use(restify.plugins.acceptParser(server.acceptable));
  38. server.use(restify.plugins.queryParser());
  39. server.use(restify.plugins.bodyParser());
  40. const cors = corsMiddleware({
  41. credentials: true,
  42. preflightMaxAge: 5,
  43. origin: function(origin, callback) {
  44. callback(null, origin);
  45. }
  46. });
  47. server.pre(cors);
  48. server.put("/register/:name", function(req, res, next) {
  49. const existingRecord = db.get(`/users/${req.params.name}`);
  50. if (existingRecord) {
  51. res.send({ error: errors.register.exists });
  52. } else {
  53. db.update(`/users/${req.params.name}`, {
  54. password: req.body.password
  55. });
  56. const dbEntry = db.get(`/users/${req.params.name}`);
  57. res.send(dbEntry);
  58. return next();
  59. }
  60. });
  61. server.put("/vote/:name", function(req, res, next) {
  62. const user = db.get(`/users/${req.params.name}`);
  63. if (user && req.body.password === user.password) {
  64. db.set(`/votes/${req.params.name}`, { factions: req.body.factions });
  65. const dbEntry = db.get(`/votes/${req.params.name}`);
  66. res.send(dbEntry);
  67. } else {
  68. res.send({ error: errors.vote.baduser });
  69. }
  70. return next();
  71. });
  72. server.put("/game/:timestamp", function(req, res, next) {
  73. const user = db.get(`/users/${req.params.name}`);
  74. if (user && req.body.password === user.password) {
  75. const game = db.get(`/games/${req.params.timestamp}`);
  76. db.set(`/games/${req.params.timestamp}`, { ...game, ...req.body });
  77. const dbEntry = db.get(`/games/${req.params.timestamp}`);
  78. res.send(dbEntry);
  79. } else {
  80. res.send({ error: errors.vote.baduser });
  81. }
  82. return next();
  83. });
  84. server.get("/game/:timestamp", function(req, res, next) {
  85. const user = db.get(`/users/${req.params.name}`);
  86. if (user && req.body.password === user.password) {
  87. const dbEntry = db.get(`/games/${req.params.timestamp}`);
  88. res.send(dbEntry);
  89. } else {
  90. res.send({ error: errors.vote.baduser });
  91. }
  92. return next();
  93. });
  94. server.post("/games", function(req, res, next) {
  95. const user = db.get(`/users/${req.body.name}`);
  96. if (user && req.body.password === user.password) {
  97. const dbEntry = db.get(`/games`);
  98. res.send(dbEntry);
  99. } else {
  100. res.send({ error: errors.vote.baduser });
  101. }
  102. return next();
  103. });
  104. server.get("/vote/:name", function(req, res, next) {
  105. const dbEntry = db.get(`/votes/${req.params.name}`);
  106. if (dbEntry) {
  107. res.send(dbEntry);
  108. } else {
  109. res.send({ error: errors.vote.novotes });
  110. }
  111. return next();
  112. });
  113. server.post("/user/:name", function(req, res, next) {
  114. if (req.params.name) {
  115. const userEntry = db.get(`/users/${req.params.name}`);
  116. if (userEntry) {
  117. if (req.body && userEntry.password === req.body.password) {
  118. const voteEntry = db.get(`/votes/${req.params.name}`) || [];
  119. res.send({ ...voteEntry });
  120. } else {
  121. res.send({ error: errors.user.badpassword });
  122. }
  123. } else {
  124. res.send({ error: errors.user.notfound });
  125. }
  126. } else {
  127. res.send({ error: errors.user.nouser });
  128. }
  129. return next();
  130. });
  131. function lockChoices() {
  132. const dbEntry = db.get(`/votes`);
  133. function customizer(objValue, srcValue) {
  134. if (_.isArray(objValue)) {
  135. return objValue.concat(srcValue);
  136. }
  137. }
  138. const allChoices = Object.keys(dbEntry).reduce((acc, player) => {
  139. const achoices = dbEntry[player].factions.reduce((acc, factionChoice) => {
  140. return _.mergeWith(
  141. acc,
  142. {
  143. [factionChoice.id]: { ...factionChoice, chosenBy: [player] }
  144. },
  145. customizer
  146. );
  147. }, {});
  148. return _.mergeWith(acc, achoices, customizer);
  149. }, {});
  150. let notPicked = Object.keys(allChoices).reduce((acc, factionId) => {
  151. return acc.filter(faction => {
  152. return Number(faction.id) !== Number(factionId);
  153. });
  154. }, factions);
  155. const resolved = Object.keys(dbEntry).reduce((acc, player) => {
  156. const resolvedChoices = dbEntry[player].factions.map(factionChoice => {
  157. return {
  158. ...factionChoice,
  159. unique: allChoices[factionChoice.id].chosenBy.length < 2
  160. };
  161. });
  162. let selected = resolvedChoices.find(choice => choice.unique);
  163. if (!selected) {
  164. const randomId = Math.floor(Math.random() * (notPicked.length - 1));
  165. selected = notPicked[Object.keys(notPicked)[randomId]];
  166. notPicked = notPicked.filter(faction => faction.id !== selected.id);
  167. }
  168. return { ...acc, [player]: { choices: resolvedChoices, selected } };
  169. }, {});
  170. db.set("/factionChoices", resolved);
  171. return resolved;
  172. }
  173. server.get("/votes", function(req, res, next) {
  174. const revealDate = 1618077600 * 1000;
  175. if (Date.now() >= revealDate) {
  176. const choices = db.get("/factionChoices") || lockChoices();
  177. res.send(choices);
  178. } else {
  179. const dbEntry = db.get(`/votes`);
  180. res.send({ error: errors.votes.toosoon, voted: Object.keys(dbEntry) });
  181. }
  182. return next();
  183. });
  184. // test comment
  185. server.listen(8082, function() {
  186. console.log("%s listening at %s", server.name, server.url);
  187. });