You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

238 regels
4.7 KiB

  1. const roles = require('../../config/roles');
  2. const events = require('../../misc/events');
  3. const profanities = require('../../misc/profanities');
  4. const canChat = require('./canChat');
  5. const sendRegularMessage = ({ obj }, messageInfo) => {
  6. const { source, msg, item } = messageInfo;
  7. const prefix = roles.getRoleMessagePrefix(obj) || '';
  8. const prefixClass = roles.getRoleMessageStyle(obj) || 'color-grayB';
  9. const msgClass = item ? `q${item.quality}` : 'color-grayB';
  10. cons.emit('event', {
  11. event: 'onGetMessages',
  12. data: {
  13. messages: [{
  14. type: 'chat',
  15. source,
  16. prefix,
  17. prefixClass,
  18. msg,
  19. msgClass,
  20. item
  21. }]
  22. }
  23. });
  24. };
  25. const sendPartyMessage = ({ party, obj }, msg) => {
  26. if (!party) {
  27. obj.socket.emit('events', {
  28. onGetMessages: [{
  29. messages: [{
  30. class: 'color-redA',
  31. message: 'you are not in a party',
  32. type: 'info'
  33. }]
  34. }]
  35. });
  36. return;
  37. }
  38. let charname = obj.auth.charname;
  39. let message = msg.data.message;
  40. party.forEach(p => {
  41. let player = cons.players.find(c => c.id === p);
  42. player.socket.emit('events', {
  43. onGetMessages: [{
  44. messages: [{
  45. class: 'color-tealC',
  46. message: '(party: ' + charname + '): ' + message,
  47. type: 'chat',
  48. source: obj.name
  49. }]
  50. }]
  51. });
  52. });
  53. };
  54. const sendCustomChannelMessage = (cpnSocial, msg) => {
  55. const { obj } = cpnSocial;
  56. const { data: { message, subType: channel } } = msg;
  57. if (!channel)
  58. return;
  59. if (!cpnSocial.isInChannel(obj, channel)) {
  60. obj.socket.emit('events', {
  61. onGetMessages: [{
  62. messages: [{
  63. class: 'color-redA',
  64. message: 'You are not currently in that channel',
  65. type: 'info'
  66. }]
  67. }]
  68. });
  69. return;
  70. }
  71. const sendMessage = `[${channel}] ${obj.auth.charname}: ${message}`;
  72. const eventData = {
  73. onGetMessages: [{
  74. messages: [{
  75. class: 'color-grayB',
  76. message: sendMessage,
  77. type: 'chat',
  78. subType: 'custom',
  79. channel: channel.trim(),
  80. source: obj.name
  81. }]
  82. }]
  83. };
  84. cons.players.forEach(p => {
  85. if (!cpnSocial.isInChannel(p, channel))
  86. return;
  87. p.socket.emit('events', eventData);
  88. });
  89. };
  90. const sendPrivateMessage = ({ obj: { name: sourceName, socket } }, msg) => {
  91. const { data: { message, subType: targetName } } = msg;
  92. if (targetName === sourceName)
  93. return;
  94. let target = cons.players.find(p => p.name === targetName);
  95. if (!target)
  96. return;
  97. socket.emit('event', {
  98. event: 'onGetMessages',
  99. data: {
  100. messages: [{
  101. class: 'color-yellowB',
  102. message: '(you to ' + targetName + '): ' + message,
  103. type: 'chat',
  104. subType: 'privateOut',
  105. target: targetName
  106. }]
  107. }
  108. });
  109. target.socket.emit('event', {
  110. event: 'onGetMessages',
  111. data: {
  112. messages: [{
  113. class: 'color-yellowB',
  114. message: '(' + sourceName + ' to you): ' + message,
  115. type: 'chat',
  116. subType: 'privateIn',
  117. source: sourceName
  118. }]
  119. }
  120. });
  121. };
  122. const sendErrorMsg = (cpnSocial, msgString) => {
  123. cpnSocial.sendMessage(msgString, 'color-redA');
  124. };
  125. module.exports = (cpnSocial, msg) => {
  126. const { data: msgData } = msg;
  127. if (!msgData.message)
  128. return;
  129. const { obj, maxChatLength, messageHistory } = cpnSocial;
  130. const sendError = sendErrorMsg.bind(null, cpnSocial);
  131. msgData.message = msgData.message
  132. .split('<')
  133. .join('&lt;')
  134. .split('>')
  135. .join('&gt;');
  136. if (!msgData.message)
  137. return;
  138. if (msgData.message.trim() === '')
  139. return;
  140. let messageString = msgData.message;
  141. if (messageString.length > maxChatLength)
  142. return;
  143. let time = +new Date();
  144. messageHistory.spliceWhere(h => ((time - h.time) > 5000));
  145. if (messageHistory.length) {
  146. if (messageHistory[messageHistory.length - 1].msg === messageString) {
  147. sendError('You have already sent that message');
  148. return;
  149. } else if (messageHistory.length >= 3) {
  150. sendError('You are sending too many messages');
  151. return;
  152. }
  153. }
  154. cpnSocial.onBeforeChat(msgData);
  155. if (msgData.ignore)
  156. return;
  157. if (!msgData.item && !profanities.isClean(messageString)) {
  158. sendError('Profanities detected in message. Blocked.');
  159. return;
  160. }
  161. if (!canChat(obj, time)) {
  162. sendError('Your character needs to be played for at least 3 minutes or be at least level 3 to be able to send messages in chat.');
  163. return;
  164. }
  165. const msgEvent = {
  166. source: obj.auth.charname,
  167. sourceObj: obj,
  168. msg: messageString,
  169. ignore: false,
  170. item: msg.data.item,
  171. error: null
  172. };
  173. events.emit('onBeforeSendMessage', msgEvent);
  174. if (msgEvent.ignore) {
  175. if (msgEvent.error)
  176. sendError(msgEvent.error);
  177. return;
  178. }
  179. messageHistory.push({
  180. msg: msgEvent.msg,
  181. time: time
  182. });
  183. const messageHandler = {
  184. global: sendRegularMessage,
  185. custom: sendCustomChannelMessage,
  186. direct: sendPrivateMessage,
  187. party: sendPartyMessage
  188. }[msgData.type];
  189. if (!messageHandler)
  190. return;
  191. messageHandler(cpnSocial, msgEvent);
  192. };