stats.lua 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. function lobby.update_stats(map_id, mode, win, player_count, play_time)
  2. local stats = lobby.savedata.stats[map_id] or {}
  3. local server_stats = lobby.savedata.stats['server'] or {}
  4. stats.solo_play = stats.solo_play or 0
  5. stats.multi_play = stats.multi_play or 0
  6. stats.winner_traitor = stats.winner_traitor or 0
  7. stats.winner_team = stats.winner_team or 0
  8. stats.player_count = stats.player_count or 0
  9. stats.max_players = stats.max_players or 0
  10. stats.max_play_time = stats.max_play_time or 0
  11. stats.avg_play_time = stats.avg_play_time or 0
  12. server_stats.max_players = server_stats.max_players or 0
  13. server_stats.most_played = server_stats.most_played or 0
  14. server_stats.team_wins = server_stats.team_wins or 0
  15. server_stats.traitor_wins = server_stats.traitor_wins or 0
  16. server_stats.max_play_time = server_stats.max_play_time or 0
  17. if win == 'traitor' then
  18. stats.winner_traitor = stats.winner_traitor + 1
  19. if stats.winner_traitor > server_stats.traitor_wins then
  20. server_stats.traitor_wins = stats.winner_traitor
  21. server_stats.traitor_wins_id = map_id
  22. end
  23. elseif win == 'team' then
  24. stats.winner_team = stats.winner_team + 1
  25. if stats.winner_team > server_stats.team_wins then
  26. server_stats.team_wins = stats.winner_team
  27. server_stats.team_wins_id = map_id
  28. end
  29. end
  30. if player_count then --takes an integer as input
  31. local count = stats.multi_play
  32. local avg = stats.player_count
  33. local total = count * avg
  34. local player_count_avg = (total + player_count) / (count + 1)
  35. stats.player_count = player_count_avg
  36. if player_count > stats.max_players then
  37. stats.max_players = player_count
  38. end
  39. if player_count > server_stats.max_players then
  40. server_stats.max_players = player_count
  41. server_stats.max_players_id = map_id
  42. end
  43. end
  44. if mode == 'solo' then --Solo sessions played.
  45. stats.solo_play = stats.solo_play + 1
  46. elseif mode == 'player' then --Team sessions played.
  47. stats.multi_play = stats.multi_play + 1
  48. if stats.multi_play > server_stats.most_played then
  49. server_stats.most_played = stats.multi_play
  50. server_stats.most_played_id = map_id
  51. end
  52. end
  53. if play_time then
  54. local avg = stats.avg_play_time
  55. local count = stats.multi_play
  56. local total = count * avg
  57. local avg_play_time = (total + play_time) / (count + 1)
  58. stats.avg_play_time = avg_play_time
  59. if play_time > stats.max_play_time then
  60. stats.max_play_time = play_time
  61. end
  62. if play_time > server_stats.max_play_time then
  63. server_stats.max_play_time = play_time
  64. server_stats.max_play_time_id = map_id
  65. end
  66. end
  67. lobby.savedata.stats[map_id] = stats
  68. lobby.savedata.stats['server'] = server_stats
  69. end
  70. function lobby.retrieve_stats(map_id)
  71. local formspec = 'formspec_version[3]'..
  72. 'size[16,9]'..
  73. 'background[-1,-1;18,11;lobby_stats.png]'
  74. if lobby.savedata.stats[map_id] then
  75. local data = lobby.savedata.data[map_id]
  76. local map_name = data['map_name'] or map_id
  77. local stats = lobby.savedata.stats[map_id]
  78. local solo = stats.solo_play
  79. local player = stats.multi_play
  80. local traitor = stats.winner_traitor
  81. local team = stats.winner_team
  82. local avg_players = stats.player_count
  83. local avg_play_time = stats.avg_play_time or 0
  84. local max_play_time = stats.max_play_time or 0
  85. local max = stats.max_players or 0
  86. if avg_players > max then
  87. avg_players = max
  88. end
  89. local avg = string.format("%.2f", avg_players)
  90. avg_play_time = string.format("%.2f", avg_play_time)
  91. max_play_time = string.format("%.2f", max_play_time)
  92. formspec = formspec ..
  93. 'label[.5,.5;Viewing stats for '..map_name..', ('..map_id..')]'..
  94. 'textarea[.5,1;7.5,4;;; This level has been played '..player..' times.'..
  95. ' On average '..avg..' players join a session. The most ever recorded was '..max..'!'..
  96. ' The average game lasts '..avg_play_time..' seconds. The longest game on record was '..max_play_time..' seconds!'..
  97. ' The traitor has won '..traitor..' games, whereas '..team..' have been team wins.\n'..
  98. ' This level has been visited by single players '..solo..' time(s).]'..
  99. 'textarea[8.5,.5;7,4.5;;; What does this all mean and why should you care?\n'..
  100. ' If you find that your level\'s wins strongly favor one party you might want to tweak the number of tasks,'..
  101. ' the granted XP, or the required XP. People are more likely to play your level when the chances of winning are fairly even.'..
  102. ' You may find that the wins don\'t add up to the times played, that is due to crashes. :(]'
  103. else
  104. formspec = formspec ..
  105. 'formspec_version[3]'..
  106. 'size[16,9]'..
  107. 'background[-1,-1;18,11;lobby_stats.png]'..
  108. 'label[.5,2;No data on this level yet! Get some friends and play a round.]'
  109. end
  110. formspec = formspec .. lobby.server_stats()
  111. return formspec
  112. end
  113. function lobby.server_stats()
  114. local stats = lobby.savedata.stats['server']
  115. local max_players = stats.max_players
  116. local max_id = stats.max_players_id
  117. local max_name = lobby.savedata.id_2_name[max_id] or 'undefined'
  118. local most_players = stats.most_played
  119. local most_id = stats.most_played_id
  120. local most_name = lobby.savedata.id_2_name[most_id] or 'undefined'
  121. local traitor_wins = stats.traitor_wins
  122. local traitor_id = stats.traitor_wins_id
  123. local traitor_name = lobby.savedata.id_2_name[traitor_id] or 'undefined'
  124. local team_wins = stats.team_wins
  125. local team_id = stats.team_wins_id
  126. local team_name = lobby.savedata.id_2_name[team_id] or 'undefined'
  127. local max_play_time = stats.max_play_time or 0
  128. local max_play_time_id = stats.max_play_time_id
  129. local max_play_time_name = lobby.savedata.id_2_name[max_play_time_id] or 'undefined'
  130. max_play_time = string.format("%.2f", max_play_time)
  131. local formspec =
  132. 'textarea[.5,5.25;15,3.25;;;Serverwide Stats and Rankings:\n'..
  133. max_name..' has the highest player count of any level with '..max_players..' playing at once.\n'..
  134. most_name..' is the most played level, being played '..most_players..' times.\n'..
  135. 'Traitors have won '..traitor_wins..' times on '..traitor_name..'.\n'..
  136. 'Teams have won '..team_wins..' times on '..team_name..'.\n'..
  137. max_play_time_name..' has the longest play time on record at '..max_play_time..' seconds!]'
  138. return formspec
  139. end
  140. function lobby.stats_overview(name, max)
  141. local formspec =
  142. 'formspec_version[3]'..
  143. 'size[16,9]'..
  144. 'background[-1,-1;18,11;lobby_stats.png]'..
  145. 'label[.5,.5;Viewing stats for your maps with auto assigned IDs.]'..
  146. 'tableoptions[background=#00000000;border=false;highlight_text=#000000;highlight=#6e9fca]'..
  147. 'tablecolumns[text,width=16;text,align=right;text,align=right;text,align=right;text,align=right;text,align=right;text,align=right;text,align=right]'..
  148. 'table[.5,1;15,7.5;stats;Map Name,Play Count, Avg Players, Avg Play Time, Traitor Wins, Team Wins, Max Players, Solo Visits,'
  149. for i = 1, max do
  150. local map_id = name..'_'..i
  151. local data = lobby.savedata.data[map_id]
  152. if data then
  153. local map_name = data['map_name'] or '[unnamed]'
  154. local stats = lobby.savedata.stats[map_id]
  155. if stats then
  156. local solo = stats.solo_play or 0
  157. local player = stats.multi_play or 0
  158. local traitor = stats.winner_traitor or 0
  159. local team = stats.winner_team or 0
  160. local avg_play_time = stats.avg_play_time or 0
  161. local avg_players = stats.player_count or 0
  162. local max = stats.max_players or 0
  163. avg_play_time = string.format("%.2f", avg_play_time)
  164. formspec = formspec ..
  165. map_name..','..player..','..avg_players..','..avg_play_time..','..traitor..','..team..','..max..','..solo..','
  166. end
  167. end
  168. end
  169. formspec = formspec ..']'
  170. return formspec
  171. end
  172. minetest.register_chatcommand('stats', {
  173. description = 'View stats on a level. Provide no name to see all your stats.',
  174. func = function(name, map_name)
  175. if lobby.savedata.name_2_id[map_name] then
  176. local map_id = lobby.savedata.name_2_id[map_name]
  177. if lobby.savedata.IDs[map_id] then
  178. local data = lobby.savedata.data[map_id]
  179. if data.owner_name == name or minetest.check_player_privs(name, {server = true}) then
  180. minetest.show_formspec(name, 'lobby:stats', lobby.retrieve_stats(map_id))
  181. end
  182. end
  183. else
  184. local i = 1
  185. local map_id = name..'_'..i
  186. while lobby.savedata.IDs[map_id] do
  187. i = i + 1
  188. map_id = name..'_'..i
  189. end
  190. minetest.show_formspec(name, 'lobby:stats_overview', lobby.stats_overview(name, i))
  191. end
  192. end
  193. })