Browse Source

initial commit

master
yarrum 4 years ago
parent
commit
7e48987b5c
  1. 50
      ScratchNotes.txt
  2. BIN
      cert/chromeExported.cer
  3. 20
      cert/old/cert.pem
  4. BIN
      cert/old/chromeExported-2.cer
  5. BIN
      cert/old/chromeExported-3.cer
  6. BIN
      cert/old/chromeExported.cer
  7. 27
      cert/old/key.pem
  8. 30
      cert/old/keytmp.pem
  9. 22
      cert/server.cert
  10. 28
      cert/server.key
  11. 14
      components/common/randomString.js
  12. 16
      components/common/sleep.js
  13. 58
      components/common/wrtColor.js
  14. 29
      components/objectDefinitions.js
  15. 32
      components/players/playerCleanup.js
  16. 66
      components/players/playerMgmtFuncs.js
  17. 52
      components/serverMgmt.js
  18. 22
      components/stateMonitor.js
  19. 90
      components/testFunctions.js
  20. 18
      config/serverConfig.js
  21. 5
      log/state.json
  22. 1681
      package-lock.json
  23. 19
      package.json
  24. 44
      server.js

50
ScratchNotes.txt

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
Recreate Love Letter as Browser Game (not for profit)
Design Envisioned UI
Pick Modules around it
Express
Socket.IO
Design Data Format
- Handle Multiple Games
- Allow Invites to Game
Design Backend
Design FrontEnd
Design an Invite Feature
Make it reconnectable
No logins, but have unique IDs
Make it https
Animations
Design Chat
Design Guide on how to play
Design Bots to play against
#Basic setup with socket.io + Express
https://medium.com/@raj_36650/integrate-socket-io-with-node-js-express-2292ca13d891
#Guide for HTTPs on Express, SSL Cert
https://medium.com/@nitinpatel_20236/how-to-create-an-https-server-on-localhost-using-express-366435d61f28
#Socket.IO handling Cleaner
https://socket.io/docs/v4/server-application-structure/
#Automatic Node Reload on changes
https://stackoverflow.com/questions/45622125/how-can-i-add-live-reload-to-my-nodejs-server
#socket.io, socket attributes
https://socket.io/docs/v4/client-socket-instance/
#MEVN stack. MongoDB, Express, VueJS, NodeJs
https://vegibit.com/vue-js-express-tutorial/
https://mfikri.com/en/blog/nodejs-express-mysql-vue
Install VUE Global
npm install -g @vue/cli
vue --version
___________________________________________________________________

BIN
cert/chromeExported.cer

Binary file not shown.

20
cert/old/cert.pem

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDWzCCAkOgAwIBAgIURu8OfAXOa5Hi1BdJO2SxEgrItuMwDQYJKoZIhvcNAQEL
BQAwPTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1PMSEwHwYDVQQKDBhJbnRlcm5l
dCBXaWRnaXRzIFB0eSBMdGQwHhcNMjIwMjI1MTcwODUzWhcNMjMwMjI1MTcwODUz
WjA9MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTU8xITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ANBWoQWSX8iyRuuMzN78ALkVLoEDGhQivpAj18n5VT4WNhpT3z7Gj2B2w6w3vsKv
XN28qILNBUcApzHMCawk4XyGgkTrFQzs2jTm5DKuU6dhn7lioMNzDgRVGieBuA0N
La3qa0gwem+fhJoT0Dm4tDeEoFEJeura6y0u/XRLm+uKSiLyo0tX12OYjgbbWh8Q
32aE6p0QqcHdFYRnUs5iy/SLkmYoMqNBrQWGAmjkYbHhwc2LhwvWEhv6HACE8Fk7
QkAScf8V2CX/xpgqjJWgAhTp5zE/YKWQc4RH0hF2wMmVnMEDB7vmRPSuuRBlo+7y
DZTMPjg5KZ3jAwfzbQOLew8CAwEAAaNTMFEwHQYDVR0OBBYEFM582p8EGMRs3IVj
Q7pq20cNc+FWMB8GA1UdIwQYMBaAFM582p8EGMRs3IVjQ7pq20cNc+FWMA8GA1Ud
EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAA2d+WnGBysGoZMOkLt4hkb+
UNp6oFcGNa/kd06UuEpFinsa82JPsAZWSNDNLqzTfTaUWFXCQkIGk2k/57NXOjXZ
3PhMJfjeR9jH3XRswxK9Dp8KaVyf1GTMbI6K+IKEULK/w2sOCAHEHVntIEPo5tCo
P4NAEmc0woPmm4NTqHU98zRR8Mqxu+112tOg3u+f6fr1YCI4o2jJeaDRdgivFYSr
V68YHq3GthzHxXLqynZBTReX8vF6fTzc7jaB79UFkgIuBwPscVYubk3PPJI0TQ38
rR7nHmC6yB60Zsg+1TuCG5czS/TZuJUMoqj3hjTXVxPTaLgnga7vBBa+Gw21OYQ=
-----END CERTIFICATE-----

BIN
cert/old/chromeExported-2.cer

Binary file not shown.

BIN
cert/old/chromeExported-3.cer

Binary file not shown.

BIN
cert/old/chromeExported.cer

Binary file not shown.

27
cert/old/key.pem

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA0FahBZJfyLJG64zM3vwAuRUugQMaFCK+kCPXyflVPhY2GlPf
PsaPYHbDrDe+wq9c3byogs0FRwCnMcwJrCThfIaCROsVDOzaNObkMq5Tp2GfuWKg
w3MOBFUaJ4G4DQ0treprSDB6b5+EmhPQObi0N4SgUQl66trrLS79dEub64pKIvKj
S1fXY5iOBttaHxDfZoTqnRCpwd0VhGdSzmLL9IuSZigyo0GtBYYCaORhseHBzYuH
C9YSG/ocAITwWTtCQBJx/xXYJf/GmCqMlaACFOnnMT9gpZBzhEfSEXbAyZWcwQMH
u+ZE9K65EGWj7vINlMw+ODkpneMDB/NtA4t7DwIDAQABAoIBAAYoWVAB2ITlCAWU
PsXkat0NjDdR8SZhNIKsHIeir+tK2sSCcBm54qj2OahQaXn1lugS2GQtTRehJE/r
eOm2mVeF3jnNPO0J3xUrMdlxn5VV5FOlX50HPIXSQhii097G4e+++vbCQAwmidPH
/CKInAL8D4T1o8VnPQYz2lfimDQo7361mCytz0VEoPqAtXEHiyxq3ID9YZxFUGg1
XFo63IhFp7fJU+mjmDLcSmCO+IAz7avdPWRKr2Fz7tI0+AipaaZSi8M+ej0IqHZs
nRzhxwVz60aVmVgdZsOfemqBR9+b9TTLSxyN4j7cjPv69w1g2pUki3rtFAuyPs/x
iaifp4kCgYEA+062Qic13JvI1werJqdE/UAIbEDOt5KGHJVpLnhScwqer7q3RmCs
xKZND4WJ64WfW9z+vkinswPfPgruNok/x8qVf673PGDEXimK2/jkRy0CKzLzdcHr
3tgRRTcu5Ejr1u/VIV+9axcmmODlHUYAUbRDssqf80g6jy+e7ra2/YMCgYEA1DqE
sCN5WJsnTnA6pjhcLcC3UQxQZ5d+iCEc/nWfYRcZsKdWh7A1xY2MDEiLWqj28x4G
mtThfu1f879t/N4yasQ7QA16RBQlquY4qfBGYcwoqY5e9V4xFg6kgTl6bgdcFc7/
p7wcUm6KqD5PnxCSlOOwPlCUuPELHHXSf1YKQoUCgYBr/GGiwXiKiEJf68KmhF/H
trkn0x1AkmygYa9lsXw0RM71UfUo/6edhJw+XDJsiul0Lt0j5NJywOovncDInGdU
sX9V81f3kNkwYQdzCFsHHpb8+xLUefShuBSLum+i1pbIsBvUEHCzUKpcLN8mmgrP
EPe6HwlmH5ZSKrNPfiHZgwKBgGCRxCDV83hzGR6jCLzr9l3HTGLvxIJut9+/mY7b
/MrUFReB/Wi+sKkU8H4CYI6/Rad4qS644Wa9IqUqHSUsAir84a0StOjXdhBes7f4
Ij6MBJCqvODPnGxZ+1blzaTVanxt9Xzgps6HiEZoHBjYFKr1NBQW3KWO4SxxHHhe
sUp1AoGADiduIMYTCQK9tTwzC+wi8L9ZzRzg8Bv9WoJwlOJ9UzebxZuoSE079WZy
R83WGVMfrGoRvt5o5zPPjXE1OVb1ZH/zqVxMqtXyNKpkaNA3zg3B+yd0t6j7r6KF
3rmR4RZQ4tvG4zSvoB6wRnQCMu5yT4Hy5UCO2okxUf/9ipkBxrI=
-----END RSA PRIVATE KEY-----

30
cert/old/keytmp.pem

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIe3/Wm4HexdMCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECHFVtycBEqVCBIIEyLgm/RkRojyc
D/pETZ9wG1BLaZC3ej6Gf1hYz3YN2ZAqXnRlNJcgniFw55QrxJxo1v9xQHacl8XR
BHTHozqegvbZBGV2ejrvHC5Ej0iFcoGez2Xo7UF+C7+qwPc1d6JjYTyev0hdfPN3
jfqbpIhVG2iErG+VJeJm/HHDd6u3ikpxevfExwscDIC/LP9jMkvJQEvoSZIOjt1u
IU+i4OZa/ex+7rVtye+g+kXIzAF+hX6xf98Ra7grjc7MltRnvELXvFTgh42q5BeS
IWYgZDTDavsplMFp9khSBaweK1Lg7nNvRJ+3xhJmqQK9IBuO24SCPSP7eDlmdHds
KuOSa2wLHLl0Wj0ogd8TBV+Lu9RJplVrTuHumBVUrCgin0pgMT5pvrGNZBaF7lyf
oSMTTCizQglsXU/PaoS7MfAtTVM6QqPGKfdFS/QhdfWgeb6RXu1Uhc0e4FxrMBYF
nJPw+8InXRygXjLO9oGPmW2w9KycuxIxtsT7hFWEUqRS5zjXKE643DEgrRFuBaTT
08Tsd5W1H6Na9Madj48OHJ/lp4O27HsJn5WebbkQQhS2g+OTObgYX7FvLs8DFyQ9
6OfIE9jMmTdxwI1EuIyDsTlRhGcF7K8gs7Zpt8F0VBE3U1zQNxdtwS0sR5azZa1+
mU1Twp5TfYW10jvWGES4VPNiwTIcPLhIBr8t+x4wqejBvpW5Ya4M2uEBSi30TKSk
YGAx1++Xmm8zKXnr42S7Xk8FfmXNmOOj0hHerdqw7vMwnQt/4n5xNafsvAL3Yd3e
6X1n6wiRF/KtkBi9CtQc+yL8+QZSAr0S1V6rfwi3arZG5QxAi3bAtPghll+XeICl
W/UDus9QCWKU6MjStXH7X7hAIHOJrr7+9WxAHFG1KNVg18Xb/D5dKP6+6GDptXHG
sH/K43cqJu50pwTxk9/wyfmUOrxYuSauwX42hIahppnxLKh3MPZ2PsVLegT/KDhR
KX+QBKup0+0oqGoATe91GWIQZXFcPCYQabQegL+p9fFjDiW3kCbJAa5wnxxI4dCk
W044AsQdg+80qZckJmJ6+LwmPsKzxwgwOoCrVp8e4XIsl9IGKkOBRj4BdN1OqjJa
dH/ogI1rIst8lbfiEbk6jilFr/gsDDQwuZNU9QbHWTj+/HjPEIEL4QCQDPCSOyTP
5+FWqxrn04k7ThqMegPzwXPMvPtA6BmCZ4Vl4eKS1S0u9WfitDOYyng+H42/u3Ji
73GUVEmZ73RT4jPPDjS02y/Owvx5FLa9bs0rcd9fBVJay+dPovHmrQknj4lcziC4
ly9AzaQByEHIoViiJuagU1MjxA9EJUa0FJ12g1lOr0HfeypWzCsleHQCPkGTyJQX
FyrQq8q0Jf38L5h2KEtF6Po1bUL+F7S6cwpkFkYGgsAYM+zpMVT2kXA0pP75Ca+g
w+HKRhXgbMmqKDuJTbs4UHgeofqrb+T3rXyk4gfgjNXmNfzwaoENKDVHiv7yp8Og
6qs2vdphNaxSf4iKd/ybaCAzCJlWnWEGUqyhYfKYaFJAmQx8fhw7zGRD2I8lKGz+
YW7hGnmLUB68M7i1QUHHDBm8hxLSaSJPyOIHnKhX06DTuHyIsPmfi8i3VAkzkiaV
t4drORAApx1BSzNTI0xTWg==
-----END ENCRYPTED PRIVATE KEY-----

22
cert/server.cert

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDpzCCAo+gAwIBAgIUVgja2cJarOptGTXo5bwdUx2WGLswDQYJKoZIhvcNAQEL
BQAwYzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1PMQswCQYDVQQHDAJLQzESMBAG
A1UECgwJbG9jYWxob3N0MRIwEAYDVQQLDAlsb2NhbGhvc3QxEjAQBgNVBAMMCWxv
Y2FsaG9zdDAeFw0yMjAzMjkxNzU5MjVaFw0yMjA0MjgxNzU5MjVaMGMxCzAJBgNV
BAYTAlVTMQswCQYDVQQIDAJNTzELMAkGA1UEBwwCS0MxEjAQBgNVBAoMCWxvY2Fs
aG9zdDESMBAGA1UECwwJbG9jYWxob3N0MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpc68E8r32hLbMPUawJZwTaQn2
RoGMHoOSzfHqOXcjF0D0QIOgeO2uMYJ6nMh4AfSKjRkOK2oJO4fknp72ArrK+S7x
KVaMg6T0FaVsffFYJO8/aujUBhnEyF+dAtyveABfMrJwU+/uTuwKJAJz7wvOl+3/
7Idop49PAWo64HYlJkl3iQUuVmBL2kpyrHLNnTIT8HBKsLJVnO2IzozQnTrI0CnF
PFgdqjdPyTurJYhIYRNsSL1ZpTBdWoeZPCWIjYGr9X4Om4aaAkD3bWmaPNYwIaja
GwBaCfKTnGw9+EWDXrQxZfpOqVJp/19ZFTsoMGIJo0LtPRgmOwAFkjSfXwArAgMB
AAGjUzBRMB0GA1UdDgQWBBRFm+iZPyUN8ZMfGfnWO3iBbas15DAfBgNVHSMEGDAW
gBRFm+iZPyUN8ZMfGfnWO3iBbas15DAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
DQEBCwUAA4IBAQDacoUJOm0Y8vm8hwqgqres3kYD2sQAYMsU146hfUeNfcRXIYYK
TLFiu6/bEc+85riZerZQCDFzPcVGJT4NPTkQkofYhkPG8UpDdEH/o8kZn5icDYoX
KcB/V8mOtSi+zN3Hol88XmfMkFDxeNYkUvI2vfycAE8PR21pKcnR6UROZBkMuCMC
p/wJY6cmaPNKwZGaGLWqlNcOFV1xEYQnFYm3IYsBjnQslhyU4Wpnd6MiZQ3uoerk
9fl4IGsu3BAkTkdAaibsnmUp4/SorvGoYi+hGJ/NvPherMjsINVP5MNH+uUqf2QT
f6nor/JgODkq1BXSAYJxY4xtD6hYNm/qWh6w
-----END CERTIFICATE-----

28
cert/server.key

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDpc68E8r32hLbM
PUawJZwTaQn2RoGMHoOSzfHqOXcjF0D0QIOgeO2uMYJ6nMh4AfSKjRkOK2oJO4fk
np72ArrK+S7xKVaMg6T0FaVsffFYJO8/aujUBhnEyF+dAtyveABfMrJwU+/uTuwK
JAJz7wvOl+3/7Idop49PAWo64HYlJkl3iQUuVmBL2kpyrHLNnTIT8HBKsLJVnO2I
zozQnTrI0CnFPFgdqjdPyTurJYhIYRNsSL1ZpTBdWoeZPCWIjYGr9X4Om4aaAkD3
bWmaPNYwIajaGwBaCfKTnGw9+EWDXrQxZfpOqVJp/19ZFTsoMGIJo0LtPRgmOwAF
kjSfXwArAgMBAAECggEBANlkzfXYqod3HNbitQHxc/8rUIiTLa4y+ClsOLv6GXSH
AgiyTyDPm94b4rqVZ6VBhNzE+jEUwqCoXCrMf5DuB85d75XJ/fvJ14Eo6yw1t9py
Qo0W3IwcxkBWq5sGAEYyhH4iMsKhl4ue2PW0hMg7Mg6Hsq0hMROG/c//rFH5lmuO
DXuTG+iaJXbQn+TT/i2aSESuXDdKFM9LfB4k4VS+OCKYxFT38fFEI/lzeABc2tsh
g48PGdVgZjfcjVLzziwyG0TL7XjPuqSe4rFTTea79LTbXp/ck50ivqKT4TpdD7Ck
7kPTFkrXxyg74V+brD0vpJpmu54sFU2/G0z4CDZIGOECgYEA+IOEMTIqBDFtPrEc
IbBZWodfKMaOJqRq1ifypcMsZeSXNS2zjg4isdonh0WXsZXMUq04T1yh2d1MPcjP
Glc16dfpsEzF/f96ujjCJ7RA+QjQQ3K8mVAfjLr9hRbrqCMVHLo5DQ+rw5Uw5C6o
6z8ZeexFxLsHKh341akKi0waKHECgYEA8HwDfOhtsCySbSW65+h2y77K4s+EYyPh
6V0fGrIDrUtGVkAfmkpMEpjU+qempklKt5/mFqkWkXbjGUD+vz413ZMObsXaEPKU
JZ+XGuD9D80vfxqZp7w3Fjhzh8A23jYICFv3joZ0qs5M5jV67nFCW0ffh4ehD6dZ
o5N/CUuMoFsCgYEAzJ8tl3xgkDdKZlZafXrA+AOC3QYwQa0bst4Ns2MzCWrg/g51
S8Bj3OFtrroknzpilKjANshlFAhdIHpZ3Kx2XedEKb/tPqi/mtnlM9/9p5AUO5Ub
qXkJoUzONmma/ER2u8Kx+wkuOsp7CUdKGvlHttZO1B/TVGB9ZR/c6LluyGECgYEA
v9iPB8R8TMEiBwTEeGFQ8/U+8XXPDTAA9yQcvjUpDcQxVnlNPM7spSFbNqMsJRfv
DVH4QjeeE2meffUFxRch7aN1LhWUg1ShruoDp6O4/jQYIfPchJ137LgYIkHLA7Zi
7hhAA2lsBR8S5cvgR/v+jcdmoT4n1M8SiZYPECE/DGUCgYEAnh5lIWpDdw2vcnW4
/lgb1I9oXRZcLIYha+WhC6PXHAUqdTAk+afefmjF1QEIgu2lYZQU28TZDcTn2OgN
PVPuKItJjoTz/c6npgLABkn6dDuRfnAfFV2tj6mPmqQ70A9B8B4ql3f3tbiQOQPC
ZXPCc/cVEOJnBGT7wtZTdhP6eV8=
-----END PRIVATE KEY-----

14
components/common/randomString.js

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
let validCharacters = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
genRandomString = (stringLength) => {
let newString = ''
for (let i = 0; i < stringLength; i++) {
$index = Math.floor(Math.random() * 35)
newString += validCharacters[$index]
}
return newString
}
module.exports = {
genRandomString: genRandomString
}

16
components/common/sleep.js

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
// // sleep function
// const sleep = (milliseconds) => {
// const date = Date.now()
// let currentDate = null
// do {
// currentDate = Date.now()
// } while (currentDate - date < milliseconds)
// }
const sleep = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms))
}
module.exports = {
sleep: sleep
}

58
components/common/wrtColor.js

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
// Make console colors
// based on what I found here:
// https://www.kindacode.com/article/node-js-colorizing-console-log-output/
// color chart found here:
// https://en.m.wikipedia.org/wiki/ANSI_escape_code#Colors
// // red
// console.log('\x1b[31m%s\x1b[0m', 'I am red')
// // green
// console.log('\x1b[32m%s\x1b[0m', 'I am green')
// // yellow
// console.log('\x1b[33m%s\x1b[0m', 'I am yellow')
// // blue
// console.log('\x1b[34m%s\x1b[0m', 'I am blue')
// // magenta
// console.log('\x1b[35m%s\x1b[0m', 'I am magenta')
// // cyan
// console.log('\x1b[36m%s\x1b[0m', 'I am cyan')
const wrtColorRed = (text) => {
console.log('\x1b[31m%s\x1b[0m', text)
}
const wrtColorGreen = (text) => {
console.log('\x1b[32m%s\x1b[0m', text)
}
const wrtColorYellow = (text) => {
console.log('\x1b[33m%s\x1b[0m', text)
}
const wrtColorBlue = (text) => {
console.log('\x1b[34m%s\x1b[0m', text)
}
const wrtColorMagenta = (text) => {
console.log('\x1b[35m%s\x1b[0m', text)
}
const wrtColorCyan = (text) => {
console.log('\x1b[36m%s\x1b[0m', text)
}
const wrtErr = (text) => { //Black on Red
console.log('\x1b[30;41m%s\x1b[0m', text)
}
const wrtWarn = (text) => { //Black on Red
console.log('\x1b[30;43m%s\x1b[0m', text)
}
const wrtTest = (text) => { // Green on Black
console.log('\x1b[92;100m%s\x1b[0m', text)
}
module.exports = {
red: wrtColorRed,
green: wrtColorGreen,
yellow: wrtColorYellow,
blue: wrtColorBlue,
magenta: wrtColorMagenta,
cyan: wrtColorCyan,
err: wrtErr,
warn: wrtWarn,
test: wrtTest,
}

29
components/objectDefinitions.js

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
// Object Definitions
class player {
constructor (userid,
username,
gameid,
lastActivity,
connected) {
this.userid = userid
this.username = username
this.gameid = gameid
this.lastActivity = lastActivity
this.connected = connected
}
}
class table {
}
class game {
}
// Object Initialization
let state = {
players:[],
tables:[],
games:[]
}
module.exports = {
state: state,
players: state.players
}

32
components/players/playerCleanup.js

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
const serverConfig = require('../../config/serverConfig.js') // Server Config
const wrtColor = require('../common/wrtColor')
// const { sleep } = require('./common/sleep')
function filterExpired(player) {
// let diff = ((new Date())-player.lastActivity)
// console.log(`${player.username} diff: ${diff}`)
if (((new Date())-player.lastActivity) <= serverConfig.playerExpiration) {
return player
} else {
// console.log(`Expired Session: ${player.username}`)
wrtColor.magenta(`Expired Session: ${player.username}`)
}
}
function playerCleanup (state) {
// setInterval(function() { //<--This works, but I'm concerned about Memory Leak. I need to learn more.
// console.log(state)
// state.players = state.players.filter(checkExpired)
// }, serverConfig.cleanupInterval)
//setTimeout Version self-calling function
let timerId = setTimeout(function tick() {
// console.log(state)
state.players = state.players.filter(filterExpired)
timerId = setTimeout(tick, serverConfig.cleanupInterval)
}, serverConfig.cleanupInterval)
}
module.exports = {
playerCleanup: playerCleanup
}

66
components/players/playerMgmtFuncs.js

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
// Sends Updates to socket when players change
const wrtColor = require('../common/wrtColor')
function mapRemoveLastActivityProp (player) {
// Make this specific by props to remove
let {lastActivity, ...other} = player
// return {
// id: player.id,
// username: player.username,
// gameid: player.gameid
// }
return other
}
function continuousEmitPlayers (state,io) {
let previousPlayersRelevant = []
let timerId = setTimeout(function tick() {
// get players excluding the "lastActivity" because it is constantly updating
playersRelevant = state.players.map(mapRemoveLastActivityProp)
// console.log(playersRelevant)
// convert to string for comparison
if ((JSON.stringify(playersRelevant)) !== (JSON.stringify(previousPlayersRelevant))) {
// if changes happen, emit to all sockets
// wrtColor.blue('change to Players. Push to Sockets')
io.emit('playersUpdate', playersRelevant)
}
previousPlayersRelevant = playersRelevant
timerId = setTimeout(tick, 1000)
}, 1000)
}
function socketGetPlayers (state,socket) {
playersRelevant = state.players.map(mapRemoveLastActivityProp)
socket.emit('playersUpdate', playersRelevant)
}
function checkValidPlayerName(players,name) {
let response = {
valid: true,
reason: ""
}
// Returns True/False
// 15 character limit
// No special characters
// name not in use already
}
function socketRegisterPlayer (io,state,data) {
wrtColor.warn('socketRegisterPlayer')
console.log(data)
//console.log(state.players)
io.emit('msg',{poop:"salad"})
let checkResult = checkValidPlayerName(state.players, name)
console.log(checkResult)
// add them to state.players
}
module.exports = {
continuousEmitPlayers: continuousEmitPlayers,
socketGetPlayers: socketGetPlayers,
socketRegisterPlayer: socketRegisterPlayer,
}

52
components/serverMgmt.js

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
// const serverConfig = require('../config/serverConfig.js')
const wrtColor = require('./common/wrtColor')
//Load Object Definitions and Initialize them
require('./objectDefinitions')
let { state } = require('./objectDefinitions')
// TODO: TEST FUNCTIONS
require('./testFunctions')
const { addTestPlayers, addFluxPlayers } = require('./testFunctions')
wrtColor.test('adding Test Players')
addTestPlayers(state.players)
addFluxPlayers(state)
//--- Socket Handling ---
const { socketGetPlayers } = require('./players/playerMgmtFuncs')
const { continuousEmitPlayers } = require ('./players/playerMgmtFuncs')
const { socketRegisterPlayer } = require ('./players/playerMgmtFuncs')
function socketHandler (io) {
io.on('connection', function (socket) {
//--- Connection ---
wrtColor.cyan(`socket connection established, id ${socket.id}`)
//--- Register other socket event handler functions ---
socket.on('getPlayers', () => socketGetPlayers(state,socket))
socket.on('registerPlayer', (data) => socketRegisterPlayer(io,state,data))
//......//
//--- Disconnection ---
socket.on('disconnect', (reason) => { wrtColor.yellow(`socket disconnected, ${socket.id}, ${reason}`)})
})
//--- Continuous Processes for Sockets ---
continuousEmitPlayers(state,io)
}
//--- Continuous Server Side Processes ---
const { playerCleanup } = require('./players/playerCleanup')
const { stateMonitor } = require('./stateMonitor')
playerCleanup(state)
stateMonitor(state)
module.exports = {
socketHandler: socketHandler
}

22
components/stateMonitor.js

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
const serverConfig = require('../config/serverConfig.js') // Server Config
const wrtColor = require('./common/wrtColor')
const fs = require('fs')
function stateMonitor (state) {
setInterval(function() {
// Convert to string
let stateString = JSON.stringify(state, null, 2)
fs.writeFile(serverConfig.stateJsonPath, stateString, (err) => {
if (err) {
throw err
}
// wrtColor.blue("state.json saved")
})
}, serverConfig.stateMonitorRate)
}
module.exports = {
stateMonitor: stateMonitor
}

90
components/testFunctions.js

@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
const { genRandomString } = require('./common/randomString')
const serverConfig = require('../config/serverConfig.js')
const wrtColor = require('./common/wrtColor')
const { state } = require('./objectDefinitions')
let t = new Date()
let m15 = t.setSeconds(t.getSeconds()-15)
let p30 = t.setSeconds(t.getSeconds()+30)
let p45 = t.setSeconds(t.getSeconds()+45)
let p60 = t.setSeconds(t.getSeconds()+60)
function addTestPlayers(players) {
players.push({
id: genRandomString(serverConfig.playerIdLength),
username: 'Charlie',
gameid: 222,
lastActivity: p30,
connected: false
})
players.push({
id: genRandomString(serverConfig.playerIdLength),
username: 'Dee',
gameid: 222,
lastActivity: p45,
connected: false
})
players.push({
id: genRandomString(serverConfig.playerIdLength),
username: 'Dennis',
gameid: 222,
lastActivity: p60,
connected: false
})
players.push({
id: genRandomString(serverConfig.playerIdLength),
username: 'Frank',
gameid: 222,
lastActivity: m15,
connected: true
})
players.push({
id: genRandomString(serverConfig.playerIdLength),
username: 'Mac',
gameid: 222,
lastActivity: p30,
connected: true
})
}
function addFluxPlayers (state) {
// Add and remove Pondy from players every 5 seconds
setInterval(function () {
// PONDY
// console.log(players)
let pondyFound = false
for (let i = 0; i < state.players.length; i++) {
if (state.players[i].username === 'Pondy') {
pondyFound = true
break
}
}
if (pondyFound) {
// wrtColor.yellow('Pondy Found, removing')
let pondyFilteredPlayers = state.players.filter( function (player) {
if (player.username !== 'Pondy') {
return player
}
})
// console.log(pondyFilteredPlayers)
state.players = pondyFilteredPlayers
} else {
// wrtColor.yellow('Pondy Not Found, adding')
let t = new Date()
let p30 = t.setSeconds(t.getSeconds()+30)
state.players.push({
id: genRandomString(serverConfig.playerIdLength),
username: 'Pondy',
gameid: 222,
lastActivity: p30,
connected: true
})
}
}, 5000)
}
module.exports = {
addTestPlayers: addTestPlayers,
addFluxPlayers: addFluxPlayers
}

18
config/serverConfig.js

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
module.exports = {
// Server
certKeyPath: './cert/server.key', //Called by server.js
certPath: './cert/server.cert', //Called by server.js
httpsPort: 9000,
frontEndUrl: 'https://localhost', // Vue running from https
//PlayerCleanup
cleanupInterval: 5000, // runs every 5 seconds
playerExpiration: 60000, //300000, // 5 minutes without activity before being removed
//State Monitor
stateJsonPath: './log/state.json',
stateMonitorRate: 1000,
//Player Settings
playersUpdateCheckRate: 500, // Rate between checks to send player updates to sockets
playerNameMaxLength: 15,
playerIdLength: 6,
}

5
log/state.json

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
{
"players": [],
"tables": [],
"games": []
}

1681
package-lock.json generated

File diff suppressed because it is too large Load Diff

19
package.json

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
{
"name": "loveletter",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js",
"live": "nodemon server.js --ignore ./log/"
},
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.17.3",
"socket.io": "^4.4.1",
"vue-router": "^4.0.13"
}
}

44
server.js

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
const path = require('path')
const fs = require('fs')
const express = require('express')
const serverConfig = require('./config/serverConfig.js') // Server Config
const wrtColor = require('./components/common/wrtColor')
//Http 80 Route traffic to the frontend VUE application running with HTTPS
const http = require('http')
const httpApp = express()
httpApp.all('*', (req, res) => res.redirect(301, `${serverConfig.frontEndUrl}`)) //301 - Moved Permanently
const httpServer = http.createServer(httpApp)
httpServer.listen(80, () => {
//console.log(`http redirectiong 80 to Vue front end at ${serverConfig.frontEndUrl}`)
wrtColor.green(`http redirectiong 80 to Vue front end at ${serverConfig.frontEndUrl}`)
})
//Https to run socket.io
const https = require('https')
const httpsApp = express()
const keyPath = fs.readFileSync(path.resolve(__dirname, `${serverConfig.certKeyPath}`))
const certPath = fs.readFileSync(path.resolve(__dirname, `${serverConfig.certPath}`))
const servOptions = {
key: keyPath,
cert: certPath
}
const httpsServer = https.createServer(servOptions,httpsApp)
httpsServer.listen(serverConfig.httpsPort, () => {
//console.log(`https listening on ${serverConfig.httpsPort} to handle socket.io requests`)
wrtColor.green(`https listening on ${serverConfig.httpsPort} to handle socket.io requests`)
})
// Attach Socket.IO to https server
const io = require('socket.io') (httpsServer, {
cors: { //https://socket.io/docs/v3/handling-cors/
origin: `${serverConfig.frontEndUrl}`,
methods: ["GET", "POST"]
}
})
//load gameManagement
require('./components/serverMgmt')
//pass socket.io connections to socketHandler
const { socketHandler } = require('./components/serverMgmt.js')
socketHandler(io)
Loading…
Cancel
Save