gatno

Untitled

Nov 1st, 2017
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.58 KB | None | 0 0
  1. -- ****************************************************************************
  2. -- *
  3. -- * PROJECT: vRoleplay
  4. -- * FILE: server/classes/Player/Account.lua
  5. -- * PURPOSE: Account class
  6. -- *
  7. -- ****************************************************************************
  8. local MULTIACCOUNT_CHECK = GIT_BRANCH == "release/production" and true or false
  9.  
  10. Account = inherit(Object)
  11.  
  12. function Account.login(player, username, password, pwhash)
  13. if player:getAccount() then return false end
  14. if (not username or not password) and not pwhash then return false end
  15.  
  16. if not username:match("^[a-zA-Z0-9_.%[%]]*$") then
  17. player:triggerEvent("loginfailed", "Ungültiger Nickname. Dein Name darf nur alphanumerische Zeichen verwenden.")
  18. return false
  19. end
  20.  
  21. -- Ask SQL to fetch ForumID
  22. sql:queryFetchSingle(Async.waitFor(self), ("SELECT Id, ForumID, Name, RegisterDate FROM ??_account WHERE %s = ?"):format(username:find("@") and "email" or "Name"), sql:getPrefix(), username)
  23. local row = Async.wait()
  24. if not row or not row.Id then
  25. board:queryFetchSingle(Async.waitFor(self), "SELECT username, password, userID, email FROM wcf1_user WHERE username LIKE ?", username)
  26. local row2 = Async.wait()
  27. if row2 and row2.password then
  28. if pwhash then
  29. if pwhash == row2.password then
  30. outputConsole("Creating Account for "..username)
  31. Account.createAccount(player, row2.userID, row2.username, row2.email)
  32. return
  33. else
  34. player:triggerEvent("loginfailed", "Gespeichertes Passwort ungültig! Bitte gib dein Passwort erneut in das Eingabefeld ein.")
  35. return false
  36. end
  37. else
  38. local param = {["userId"] = row2.userID; ["password"] = password;}
  39. local data, responseInfo = Account.asyncCallAPI("checkPassword", toJSON(param))
  40. if responseInfo["success"] == true then
  41. local returnData = fromJSON(data)
  42. if not returnData then outputConsole(data, player) return end
  43. if returnData.error then
  44. player:triggerEvent("loginfailed", returnData.error)
  45. return false
  46. end
  47. if returnData.login == true then
  48. Account.createAccount(player, row2.userID, row2.username, row2.email)
  49. return
  50. else
  51. player:triggerEvent("loginfailed", "Unbekannter Fehler")
  52. return
  53. end
  54. else
  55. outputDebugString("Error@FetchRemote: "..responseInfo["statusCode"])
  56. end
  57. end
  58. end
  59. player:triggerEvent("loginfailed", "Spieler nicht gefunden!")
  60. return
  61. end
  62.  
  63. local Id = row.Id
  64. local ForumID = row.ForumID
  65. local Username = row.Name
  66. local RegisterDate = row.RegisterDate
  67.  
  68. -- Ask SQL to fetch the password from forum
  69. board:queryFetchSingle(Async.waitFor(self), "SELECT password, registrationDate FROM wcf1_user WHERE userID = ?", ForumID)
  70. local row = Async.wait()
  71. if not row or not row.password then
  72. player:triggerEvent("loginfailed", "Falscher Name oder Passwort") -- "Error: Invalid username or password"
  73. return false
  74. end
  75.  
  76. if pwhash then
  77. if pwhash == row.password then
  78. Account.loginSuccess(player, Id, Username, ForumID, RegisterDate, pwhash)
  79. else
  80. player:triggerEvent("loginfailed", "Falscher Name oder Passwort") -- Error: Invalid username or password2
  81. return false
  82. end
  83. else
  84. local param = {["userId"] = ForumID; ["password"] = password;}
  85. local data, responseInfo = Account.asyncCallAPI("checkPassword", toJSON(param))
  86. if responseInfo["success"] == true then
  87. local returnData = fromJSON(data)
  88. if not returnData then outputConsole(data, player) return end
  89. if returnData.error then
  90. player:triggerEvent("loginfailed", returnData.error)
  91. return false
  92. end
  93. if returnData.login == true then
  94. Account.loginSuccess(player, Id, Username, ForumID, RegisterDate, row.password)
  95. else
  96. player:triggerEvent("loginfailed", "Unbekannter Fehler")
  97. end
  98. else
  99. outputDebugString("Error@FetchRemote: "..responseInfo["statusCode"])
  100. end
  101. end
  102. end
  103. addEvent("accountlogin", true)
  104. addEventHandler("accountlogin", root, function(...) Async.create(Account.login)(client, ...) end)
  105.  
  106. function Account.loginSuccess(player, Id, Username, ForumID, RegisterDate, pwhash)
  107. if DatabasePlayer.getFromId(Id) then
  108. player:triggerEvent("loginfailed", "Dieser Account ist schon in Benutzung")
  109. return false
  110. end
  111.  
  112. if MULTIACCOUNT_CHECK then
  113. MultiAccount.addSerial(Id, player:getSerial())
  114.  
  115. if #MultiAccount.getAccountsBySerial(player:getSerial()) > 1 then
  116. if not MultiAccount.isAccountLinkedToSerial(Id, player:getSerial()) then
  117. if not MultiAccount.allowedToCreateAnMultiAccount(player:getSerial()) then
  118. player:triggerEvent("loginfailed", "Deine Serial wird für mehrere Accounts benutzt. Dies kann passieren, wenn sich jemand auf deinem PC mit anderen Accountdaten einloggt. Bitte melde dich im Forum (forum.exo-reallife.de) unter 'administrative Anfragen', um das Problem zu beseitigen.")
  119. return false
  120. else
  121. MultiAccount.linkAccountToSerial(Id, player:getSerial())
  122. end
  123. end
  124. end
  125. end
  126.  
  127. if not Warn.checkWarn(player, true) then
  128. -- Todo Maybe it´s more beautiful not kicking player directly only display a more information error
  129. if player and isElement(player) then player:triggerEvent("loginfailed", "Du wurdest aufgrund von 3 Warns gebannt!") end
  130. return false
  131. end
  132.  
  133. if not Ban.checkBan(player, true) then
  134. -- Todo Maybe it´s more beautiful not kicking player directly only display a more information error
  135. if player and isElement(player) then player:triggerEvent("loginfailed", "Du wurdest gebannt!") end
  136. return false
  137. end
  138.  
  139. -- Update last serial and last login
  140. sql:queryExec("UPDATE ??_account SET LastSerial = ?, LastIP = ?, LastLogin = NOW() WHERE Id = ?", sql:getPrefix(), player:getSerial(), player:getIP(), Id)
  141.  
  142. player.m_Account = Account:new(Id, Username, player, false, ForumID, RegisterDate)
  143.  
  144. if not player or not isElement(player) then -- Cause of kick directly after login (e.g. ban, warn) / Should not happened now
  145. outputDebugString("Account.loginSuccess: Player-Element for "..UserName.." not found!", 1)
  146. return
  147. end
  148.  
  149. if not Account.checkCharacter(Id) then
  150. Admin:getSingleton():sendNewPlayerMessage(player)
  151. player:createCharacter()
  152. end
  153.  
  154. player:loadCharacter()
  155. player:spawn()
  156.  
  157. StatisticsLogger:addLogin( player, Username, "Login")
  158. ClientStatistics:getSingleton():handle(player)
  159. player:triggerEvent("loginsuccess", pwhash)
  160. end
  161.  
  162. function Account.checkCharacter(Id)
  163. local row = sql:queryFetchSingle("SELECT Id FROM ??_character WHERE Id = ?", sql:getPrefix(), Id)
  164. return row and true or false
  165. end
  166.  
  167. addEvent("checkRegisterAllowed", true)
  168. addEventHandler("checkRegisterAllowed", root, function()
  169. if MULTIACCOUNT_CHECK then
  170. local playerId = MultiAccount.isSerialUsed(client:getSerial())
  171. if playerId then
  172. if not MultiAccount.allowedToCreateAnMultiAccount(client:getSerial()) then
  173. local name = Account.getNameFromId(playerId)
  174. client:triggerEvent("receiveRegisterAllowed", false, name)
  175. end
  176. end
  177. end
  178. end)
  179.  
  180. function Account.register(player, username, password, email)
  181. if player:getAccount() then return false end
  182. if not username or not password then return false end
  183.  
  184. -- Some sanity checks on the username
  185. -- Require at least 1 letter and a length of 3
  186. if not username:match("^[a-zA-Z0-9_.]*$") or #username < 3 or #username > 22 then
  187. player:triggerEvent("registerfailed", _("Ungültiger Nickname. Dein Name darf nur alphanumerische Zeichen und den Unterstrich (_) verwenden.", player))
  188. return false
  189. end
  190.  
  191. if #password < 5 then
  192. player:triggerEvent("registerfailed", _("Passwort zu kurz! Min. 5 Zeichen!", player))
  193. return false
  194. end
  195.  
  196. -- Validate email
  197. if not email:match("^[%w._-]+@[%w._-]+%.%w+$") or #email > 50 then
  198. player:triggerEvent("registerfailed", _("Ungültige eMail", player))
  199. return false
  200. end
  201.  
  202. -- Check Serial
  203. if MULTIACCOUNT_CHECK then
  204. if MultiAccount.isSerialUsed(player:getSerial()) then
  205. if not MultiAccount.allowedToCreateAnMultiAccount(player:getSerial()) then
  206. player:triggerEvent("registerfailed", _("Du besitzt bereits ein Account!", player))
  207. return false
  208. end
  209. end
  210. end
  211.  
  212. -- Check if someone uses this username already
  213. board:queryFetchSingle(Async.waitFor(self), "SELECT userID, username, email FROM wcf1_user WHERE username = ? OR email = ?", username, email)
  214. local row = Async.wait()
  215. if row then
  216. if row.username == username then
  217. player:triggerEvent("registerfailed", _("Benutzername wird bereits verwendet", player))
  218. elseif row.email == email then
  219. player:triggerEvent("registerfailed", _("Diese E-Mail wird bereits verwendet", player))
  220. end
  221.  
  222. return false
  223. end
  224.  
  225. Account.createForumAccount(player, username, password, email)
  226. end
  227. addEvent("accountregister", true)
  228. addEventHandler("accountregister", root, function(...) Async.create(Account.register)(client, ...) end)
  229.  
  230. function Account.createAccount(player, boardId, username, email)
  231. local result, _, Id = sql:queryFetch("INSERT INTO ??_account (ForumID, Name, EMail, Rank, LastSerial, LastIP, LastLogin, RegisterDate) VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW());", sql:getPrefix(), boardId, username, email, 0, player:getSerial(), player:getIP())
  232. if result then
  233. player.m_Account = Account:new(Id, username, player, false)
  234. player:createCharacter()
  235.  
  236. Account.loginSuccess(player, Id, username, boardId, RegisterDate, 0, false)
  237. else
  238. player:triggerEvent("loginfailed", "Fehler: Unable to create Ingame-Acc.")
  239. end
  240. end
  241.  
  242. function Account.guest(player)
  243. player.m_Account = Account:new(0, "Guest", player, true)
  244. player:spawn()
  245. triggerClientEvent(player, "loginsuccess", root, nil, 0)
  246. end
  247. addEvent("accountguest", true)
  248. addEventHandler("accountguest", root, function() Async.create(Account.guest)(client) end)
  249.  
  250. function Account.createForumAccount(player, username, password, email)
  251. if not password then return end
  252. local param = {["username"] = username; ["password"] = password; ["email"] = email;}
  253. local data, responseInfo = Account.asyncCallAPI("createAccount", toJSON(param))
  254. if responseInfo["success"] == true then
  255. local returnData = fromJSON(data)
  256. if not returnData then outputConsole(data, player) return end
  257. if returnData.error then
  258. player:triggerEvent("loginfailed", "Fehler: "..returnData.error)
  259. return false
  260. end
  261. if returnData.boardId then
  262. Account.createAccount(player, returnData.boardId, username, email)
  263. else
  264. player:triggerEvent("loginfailed", "Fehler: Forum-Acc konnte nicht angelegt werden")
  265. end
  266. else
  267. outputDebugString("Error@FetchRemote: "..responseInfo["statusCode"])
  268. end
  269. end
  270.  
  271. function Account.asyncCallAPI(func, postData)
  272. local options = {
  273. ["connectionAttempts"] = 1,
  274. ["postData"] = postData
  275. }
  276. fetchRemote(("https://exo-reallife.de/ingame/userApi/api.php?func=%s"):format(func), options, Async.waitFor())
  277. return Async.wait()
  278. end
  279.  
  280. function Account:constructor(id, username, player, guest, ForumID, RegisterDate)
  281. -- Account Information
  282. self.m_Id = id
  283. self.m_Username = username
  284. self.m_Player = player
  285. self.m_ForumId = ForumID
  286. self.m_RegisterDate = RegisterDate or "Unbekannt"
  287. player.m_IsGuest = guest;
  288. player.m_Id = self.m_Id
  289.  
  290. if not guest then
  291. sql:queryFetchSingle(Async.waitFor(self), "SELECT Rank, LastLogin FROM ??_account WHERE Id = ?;", sql:getPrefix(), self.m_Id)
  292. local row = Async.wait()
  293.  
  294. self.m_Rank = row.Rank
  295. self.m_LastLogin = row.LastLogin
  296.  
  297. if self.m_Rank == RANK.Banned then
  298. Ban:new(player)
  299. return
  300. end
  301. else
  302. self.m_Rank = RANK.Guest
  303. player:loadCharacter()
  304. self.m_RegisterDate = "Gast"
  305. end
  306. end
  307.  
  308. function Account:getPlayer()
  309. return self.m_Player
  310. end
  311.  
  312. function Account:getId()
  313. return self.m_Id;
  314. end
  315.  
  316. function Account:getRank()
  317. return self.m_Rank
  318. end
  319.  
  320. function Account:getRegistrationDate()
  321. return self.m_RegisterDate
  322. end
  323.  
  324. function Account:getLastLogin()
  325. return self.m_LastLogin
  326. end
  327.  
  328. function Account:getName()
  329. return self.m_Username
  330. end
  331.  
  332. function Account.getNameFromId(id)
  333. --[[sql:queryFetchSingle(Async.waitFor(self), "SELECT Name FROM ??_account WHERE Id = ?", sql:getPrefix(), id)
  334. local row = Async.wait()]]
  335. local player = Player.getFromId(id)
  336. if player and isElement(player) then
  337. return player:getName()
  338. end
  339.  
  340. local row = sql:queryFetchSingle("SELECT Name FROM ??_account WHERE Id = ?", sql:getPrefix(), id)
  341. return row and row.Name
  342. end
  343.  
  344. function Account.getBoardIdFromId(id)
  345. --[[sql:queryFetchSingle(Async.waitFor(self), "SELECT Name FROM ??_account WHERE Id = ?", sql:getPrefix(), id)
  346. local row = Async.wait()]]
  347. local player = Player.getFromId(id)
  348. if player and isElement(player) then
  349. return player:getAccount().m_ForumId
  350. end
  351.  
  352. local row = sql:queryFetchSingle("SELECT ForumID FROM ??_account WHERE Id = ?", sql:getPrefix(), id)
  353. return row and row.ForumID
  354. end
  355.  
  356. function Account.getNameFromSerial(serial)
  357. local row = sql:queryFetchSingle("SELECT Name FROM ??_account WHERE LastSerial = ?", sql:getPrefix(), serial)
  358. return row and row.Name
  359. end
  360.  
  361. function Account.getSerialAmount(serial)
  362. local result = sql:queryFetch("SELECT Id FROM ??_account WHERE LastSerial = ?", sql:getPrefix(), serial)
  363. return #result
  364. end
  365.  
  366. function Account.getLastSerialFromId(Id)
  367. local row = sql:queryFetchSingle("SELECT LastSerial FROM ??_account WHERE Id = ?", sql:getPrefix(), Id)
  368. return row.LastSerial or 0
  369. end
  370.  
  371. function Account.getIdFromName(name)
  372. local row = sql:queryFetchSingle("SELECT Id FROM ??_account WHERE Name = ?", sql:getPrefix(), name)
  373. if row and row.Id then
  374. return row.Id
  375. end
  376. return false
  377. end
  378.  
  379. function Account.getBoardIdFromName(name)
  380. local row = sql:queryFetchSingle("SELECT ForumID FROM ??_account WHERE Name = ?", sql:getPrefix(), name)
  381. return row.ForumID or 0
  382. end
Advertisement
Add Comment
Please, Sign In to add comment