Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Aug 7th, 2012  |  syntax: Lua  |  size: 17.92 KB  |  hits: 33  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. --
  2. -- toptimes_server.lua
  3. --
  4. local deleteTimeOnline = true
  5. local renameTimeOnline = true
  6. SToptimesManager = {}
  7. SToptimesManager.__index = SToptimesManager
  8. SToptimesManager.instances = {}
  9.  
  10.  
  11. ---------------------------------------------------------------------------
  12. -- Server
  13. -- Handle events from Race
  14. --
  15. -- This is the 'interface' from Race
  16. --
  17. ---------------------------------------------------------------------------
  18.  
  19. addEvent('onMapStarting')
  20. addEventHandler('onMapStarting', g_Root,
  21.         function(mapInfo, mapOptions, gameOptions)
  22.                 if g_SToptimesManager then
  23.                         g_SToptimesManager:setModeAndMap( mapInfo.modename, mapInfo.name, gameOptions.statsKey )
  24.                 end
  25.         end
  26. )
  27.  
  28. addEvent('onPlayerPickUpRacePickup')
  29. addEventHandler('onPlayerPickUpRacePickup', g_Root,
  30.         function(number, sort, model)
  31.             if sort == "vehiclechange" then
  32.                     if model == 425 then
  33.                                 --outputChatBox ( "* " .. getPlayerName(source) .. " has got the Hunter!", getRootElement(), 255, 0, 0, true )
  34.                             if g_SToptimesManager then
  35.                                     g_SToptimesManager:playerFinished( source, exports.race:getTimePassed())
  36.                                 end
  37.                         end
  38.                 end
  39.         end
  40. )
  41.  
  42. addEvent('onPlayerFinish')
  43. addEventHandler('onPlayerFinish', g_Root,
  44.         function(rank, time)
  45.                 if g_SToptimesManager then
  46.                         g_SToptimesManager:playerFinished( source, time)
  47.                 end
  48.         end
  49. )
  50.  
  51. addEventHandler('onResourceStop', g_ResRoot,
  52.         function()
  53.                 if g_SToptimesManager then
  54.                         g_SToptimesManager:unloadingMap()
  55.                 end
  56.         end
  57. )
  58.  
  59. addEventHandler('onPlayerQuit', g_Root,
  60.         function()
  61.                 if g_SToptimesManager then
  62.                         g_SToptimesManager:removePlayerFromUpdateList(source)
  63.                         g_SToptimesManager:unqueueUpdate(source)
  64.                 end
  65.         end
  66. )
  67.  
  68. addEventHandler('onResourceStart', g_ResRoot,
  69.         function()
  70.                 local raceInfo = getRaceInfo()
  71.                 if raceInfo and g_SToptimesManager then
  72.                         g_SToptimesManager:setModeAndMap( raceInfo.mapInfo.modename, raceInfo.mapInfo.name, raceInfo.gameOptions.statsKey )
  73.                 end
  74.         end
  75. )
  76.  
  77. function getRaceInfo()
  78.         local raceResRoot = getResourceRootElement( getResourceFromName( "race" ) )
  79.         return raceResRoot and getElementData( raceResRoot, "info" )
  80. end
  81.  
  82. ---------------------------------------------------------------------------
  83. --
  84. -- Events fired from here
  85. --
  86. ---------------------------------------------------------------------------
  87.  
  88. addEvent("onPlayerToptimeImprovement")
  89.  
  90. ---------------------------------------------------------------------------
  91.  
  92.  
  93. ---------------------------------------------------------------------------
  94. --
  95. -- SToptimesManager:create()
  96. --
  97. -- Create a SToptimesManager instance
  98. --
  99. ---------------------------------------------------------------------------
  100. function SToptimesManager:create()
  101.         local id = #SToptimesManager.instances + 1
  102.         SToptimesManager.instances[id] = setmetatable(
  103.                 {
  104.                         id = id,
  105.                         playersWhoWantUpdates   = {},
  106.                         updateQueue                      = {},
  107.                         serviceQueueTimer               = nil,
  108.                         displayTopCount          = 12,          -- Top number of times to display
  109.                         mapTimes                                = nil,          -- SMaptimes:create()
  110.                         serverRevision                  = 0,            -- To prevent redundant updating to clients
  111.                 },
  112.                 self
  113.         )
  114.         SToptimesManager.instances[id]:postCreate()
  115.         return SToptimesManager.instances[id]
  116. end
  117.  
  118.  
  119. ---------------------------------------------------------------------------
  120. --
  121. -- SToptimesManager:destroy()
  122. --
  123. -- Destroy a SToptimesManager instance
  124. --
  125. ---------------------------------------------------------------------------
  126. function SToptimesManager:destroy()
  127.         SToptimesManager.instances[self.id] = nil
  128.         self.id = 0
  129. end
  130.  
  131.  
  132. ---------------------------------------------------------------------------
  133. --
  134. -- SToptimesManager:postCreate()
  135. --
  136. --
  137. --
  138. ---------------------------------------------------------------------------
  139. function SToptimesManager:postCreate()
  140.         cacheSettings()
  141.         self.displayTopCount = g_Settings.numtimes
  142. end
  143.  
  144.  
  145. ---------------------------------------------------------------------------
  146. --
  147. -- SToptimesManager:setModeAndMap()
  148. --
  149. -- Called when a new map has been loaded
  150. --
  151. ---------------------------------------------------------------------------
  152. function SToptimesManager:setModeAndMap( raceModeName, mapName, statsKey )
  153.         outputDebug( 'TOPTIMES', 'SToptimesManager:setModeAndMap ' .. raceModeName .. '<>' .. mapName )
  154.  
  155.         -- Reset updatings from the previous map
  156.         self.playersWhoWantUpdates = {}
  157.         self.updateQueue = {}
  158.         if self.serviceQueueTimer then
  159.                 killTimer(self.serviceQueueTimer)
  160.         end
  161.         self.serviceQueueTimer = nil
  162.  
  163.         -- Remove old map times
  164.         if self.mapTimes then
  165.                 self.mapTimes:flush()   -- Ensure last stuff is saved
  166.                 self.mapTimes:destroy()
  167.         end
  168.  
  169.         -- Get map times for this map
  170.         self.mapTimes = SMaptimes:create( raceModeName, mapName, statsKey )
  171.         self.mapTimes:load()
  172.  
  173.         -- Get the toptimes data ready to send
  174.         self:updateTopText()
  175. end
  176.  
  177.  
  178. ---------------------------------------------------------------------------
  179. --
  180. -- SToptimesManager:unloadingMap()
  181. --
  182. -- Called when unloading
  183. --
  184. ---------------------------------------------------------------------------
  185. function SToptimesManager:unloadingMap()
  186.         if self.mapTimes then
  187.                 self.mapTimes:flush()   -- Ensure last stuff is saved
  188.         end
  189. end
  190.  
  191.  
  192. ---------------------------------------------------------------------------
  193. --
  194. -- SToptimesManager:playerFinished()
  195. --
  196. -- If time is good enough, insert into database
  197. --
  198. ---------------------------------------------------------------------------
  199. function SToptimesManager:playerFinished( player, newTime, dateRecorded )
  200.  
  201.         -- Check if top time recording is disabled for this player
  202.         if getElementData ( player, "toptimes" ) == "off" then
  203.                 return
  204.         end
  205.  
  206.         if not self.mapTimes then
  207.                 outputDebug( 'TOPTIMES', 'SToptimesManager:playerFinished - self.mapTimes == nil' )
  208.                 return
  209.         end
  210.  
  211.         dateRecorded = dateRecorded or getRealDateTimeNowString()
  212.  
  213.         local oldTime   = self.mapTimes:getTimeForPlayer( player )      -- Can be false if no previous time
  214.         local newPos    = self.mapTimes:getPositionForTime( newTime, dateRecorded )
  215.  
  216.         -- See if time is an improvement for this player
  217.         if not oldTime or newTime < oldTime then
  218.  
  219.                 local oldPos    = self.mapTimes:getIndexForPlayer( player )
  220.                 triggerEvent("onPlayerToptimeImprovement", player, newPos, newTime, oldPos, oldTime, self.displayTopCount, self.mapTimes:getValidEntryCount() )
  221.  
  222.                 -- See if its in the top display
  223.                 if newPos <= self.displayTopCount then
  224.                         outputDebug( 'TOPTIMES', getPlayerName(player) .. ' got toptime position ' .. newPos )
  225.                 end
  226.                
  227.                 outputChatBox("#ff6464[TT] #ffffff" ..getPlayerName(player) .. ' #ffffffmade a new toptime! Position: #ff6464' .. newPos .. ' #ffffffTime: #ff6464 ' .. convertMS(newTime), getRootElement(), 0, 171, 255, true)
  228.                
  229.                 if oldTime then
  230.                         outputDebug( 'TOPTIMES', getPlayerName(player) .. ' new personal best ' .. newTime .. ' ' .. oldTime - newTime )
  231.                 end
  232.  
  233.                 self.mapTimes:setTimeForPlayer( player, newTime, dateRecorded )
  234.  
  235.                 -- updateTopText if database was changed
  236.                 if newPos <= self.displayTopCount then
  237.                         self:updateTopText()
  238.                 end
  239.         end
  240.  
  241.         outputDebug( 'TOPTIMES', '++ SToptimesManager:playerFinished ' .. tostring(getPlayerName(player)) .. ' time:' .. tostring(newTime) )
  242. end
  243.  
  244. function convertMS( timeMs )
  245.  
  246.         local minutes   = math.floor( timeMs / 60000 )
  247.         local timeMs    = timeMs - minutes * 60000;
  248.  
  249.         local seconds   = math.floor( timeMs / 1000 )
  250.         local ms                = timeMs - seconds * 1000;
  251.  
  252.         return string.format( '%02d:%02d:%03d', minutes, seconds, ms );
  253. end
  254.  
  255.  
  256. ---------------------------------------------------------------------------
  257. --
  258. -- SToptimesManager:updateTopText()
  259. --
  260. -- Update the toptimes client data for the current map
  261. --
  262. ---------------------------------------------------------------------------
  263. function SToptimesManager:updateTopText()
  264.         if not self.mapTimes then return end
  265.         -- Update data
  266.  
  267.         -- Read top rows from map toptimes table and send to all players who want to know
  268.         self.toptimesDataForMap = self.mapTimes:getToptimes( self.displayTopCount )
  269.         self.serverRevision = self.serverRevision + 1
  270.  
  271.         -- Queue send to all players
  272.         for i,player in ipairs(self.playersWhoWantUpdates) do
  273.                 self:queueUpdate(player)
  274.         end
  275. end
  276.  
  277.  
  278. ---------------------------------------------------------------------------
  279. --
  280. -- SToptimesManager:onServiceQueueTimer()
  281. --
  282. -- Pop a player off the updateQueue and send them an update
  283. --
  284. ---------------------------------------------------------------------------
  285. function SToptimesManager:onServiceQueueTimer()
  286.         outputDebug( 'TOPTIMES', 'SToptimesManager:onServiceQueueTimer()' )
  287.         -- Process next player
  288.         if #self.updateQueue > 0 and self.mapTimes then
  289.                 local player = self.updateQueue[1]
  290.                 local playerPosition = self.mapTimes:getIndexForPlayer( player )
  291.                 clientCall( player, 'onServerSentToptimes', self.toptimesDataForMap, self.serverRevision, playerPosition );
  292.         end
  293.         table.remove(self.updateQueue,1)
  294.         -- Stop timer if end of update queue
  295.         if #self.updateQueue < 1 then
  296.                 killTimer(self.serviceQueueTimer)
  297.                 self.serviceQueueTimer = nil
  298.         end
  299. end
  300.  
  301.  
  302. ---------------------------------------------------------------------------
  303. --
  304. -- SToptimesManager:addPlayerToUpdateList()
  305. --
  306. --
  307. --
  308. ---------------------------------------------------------------------------
  309. function SToptimesManager:addPlayerToUpdateList( player )
  310.         if not table.find( self.playersWhoWantUpdates, player) then
  311.                 table.insert( self.playersWhoWantUpdates, player )
  312.                 outputDebug( 'TOPTIMES', 'playersWhoWantUpdates : ' .. #self.playersWhoWantUpdates )
  313.         end
  314. end
  315.  
  316. function SToptimesManager:removePlayerFromUpdateList( player )
  317.         table.removevalue( self.playersWhoWantUpdates, player )
  318. end
  319.  
  320.  
  321. ---------------------------------------------------------------------------
  322. --
  323. -- SToptimesManager:queueUpdate()
  324. --
  325. --
  326. --
  327. ---------------------------------------------------------------------------
  328. function SToptimesManager:queueUpdate( player )
  329.         if not table.find( self.updateQueue, player) then
  330.                 table.insert( self.updateQueue, player )
  331.         end
  332.  
  333.         if not self.serviceQueueTimer then
  334.                 self.serviceQueueTimer = setTimer( function() self:onServiceQueueTimer() end, 100, 0 )
  335.         end
  336. end
  337.  
  338.  
  339. function SToptimesManager:unqueueUpdate( player )
  340.         table.removevalue( self.updateQueue, player )
  341. end
  342.  
  343.  
  344. ---------------------------------------------------------------------------
  345. --
  346. -- SToptimesManager:doOnClientRequestToptimesUpdates()
  347. --
  348. --
  349. --
  350. ---------------------------------------------------------------------------
  351. function SToptimesManager:doOnClientRequestToptimesUpdates( player, bOn, clientRevision )
  352.         outputDebug( 'TOPTIMES', 'SToptimesManager:onClientRequestToptimesUpdates: '
  353.                         .. tostring(getPlayerName(player)) .. '<>' .. tostring(bOn) .. '< crev:'
  354.                         .. tostring(clientRevision) .. '< srev:' .. tostring(self.serverRevision) )
  355.         if bOn then
  356.                 self:addPlayerToUpdateList(player)
  357.                 if clientRevision ~= self.serverRevision then
  358.                         outputDebug( 'TOPTIMES', 'queueUpdate for'..getPlayerName(player) )
  359.                         self:queueUpdate(player)
  360.                 end
  361.         else
  362.                 self:removePlayerFromUpdateList(player)
  363.                 self:unqueueUpdate(player)
  364.         end
  365.  
  366. end
  367.  
  368.  
  369. addEvent('onClientRequestToptimesUpdates', true)
  370. addEventHandler('onClientRequestToptimesUpdates', getRootElement(),
  371.         function( bOn, clientRevision )
  372.                 g_SToptimesManager:doOnClientRequestToptimesUpdates( source, bOn, clientRevision )
  373.         end
  374. )
  375.  
  376.  
  377. ---------------------------------------------------------------------------
  378. --
  379. -- Commands and binds
  380. --
  381. --
  382. --
  383. ---------------------------------------------------------------------------
  384.  
  385. addCommandHandler( "deletett",
  386.         function( player, cmd, place )
  387.                 if deleteTimeOnline == false then return outputChatBox("#33ccffDeleting toptimes disabled by default",player,255,255,255,true) end
  388.                 if not _TESTING and not isPlayerInACLGroup(player, g_Settings.admingroup) then
  389.                         return
  390.                 end
  391.                 if g_SToptimesManager and g_SToptimesManager.mapTimes then
  392.                         local row = g_SToptimesManager.mapTimes:deletetime(place)
  393.                         if row then
  394.                                 g_SToptimesManager:updateTopText()
  395.                                 local mapName = tostring(g_SToptimesManager.mapTimes.mapName)
  396.                                 local placeText = place and " #" .. tostring(place) or ""
  397.                                 outputChatBox( "#FF6464[TT] #FFFFFF"..placeText.." " .. tostring(row.playerName) .. "#FFFFFF deleted by#ffffff " .. getPlayerName(player),getRootElement(), 255,55,0,true)
  398.                                 outputServerLog( "INFO: Top time"..placeText.." from '" ..tostring(row.playerName).. "' (" ..tostring(row.timeText).. " in " ..mapName.. ") deleted by " .. getAdminNameForLog(player) )
  399.                         end
  400.                 end
  401.         end
  402. )
  403.  
  404. --[[addCommandHandler( "renamett",
  405.         function( player, cmd, place , newName)
  406.                 if renameTimeOnline == false then return outputChatBox("#33ccffRenaming toptimes disabled by default",player,255,255,255,true) end
  407.                 if not _TESTING and not isPlayerInACLGroup(player, g_Settings.admingroup) then
  408.                         return
  409.                 end
  410.                 if g_SToptimesManager and g_SToptimesManager.mapTimes then
  411.                         if tonumber(place) then
  412.                                 local oldname = g_SToptimesManager.mapTimes:renameTimeForPlayer(tonumber(place),newName)
  413.                                 if oldname then
  414.                                         g_SToptimesManager:updateTopText()
  415.                                         local mapName = tostring(g_SToptimesManager.mapTimes.mapName)
  416.                                         local placeText = place and " #" .. tostring(place) or ""
  417.                                         outputChatBox( "#FFFFFF[TT] #00AAFF"..placeText.." #FFFFFF" .. tostring(oldname) .. "#00AAFF renamed to #FFFFFF" .. tostring(newName),getRootElement(), 255,55,0,true)
  418.                                         outputServerLog( "INFO: Top time"..placeText.." from '" ..tostring(oldname).. "' (" ..tostring(row.timeText).. " in " ..mapName.. ") renamed by " .. getAdminNameForLog(player).." to '" .. tostring(newName).."'"  )
  419.                                 end
  420.                         end
  421.                 end
  422.         end
  423. )--]]
  424.  
  425.  
  426. addCommandHandler( "renamett",
  427.         function( player, cmd, place , newName)
  428.                 if renameTimeOnline == false then return outputChatBox("#33ccffRenaming toptimes disabled by default",player,255,255,255,true) end
  429.                 if not _TESTING and not isPlayerInACLGroup(player, g_Settings.admingroup) then
  430.     accountname = getAccountName (getPlayerAccount(player))
  431.     if isObjectInACLGroup ( "user." .. accountname, aclGetGroup ( "Admin" ) ) then
  432.                         return
  433.                 end
  434.                            end
  435.                 if g_SToptimesManager and g_SToptimesManager.mapTimes then
  436.                         if tonumber(place) then
  437.                                 local oldname = g_SToptimesManager.mapTimes:renameTimeForPlayer(tonumber(place),newName)
  438.                                 if oldname then
  439.                                         g_SToptimesManager:updateTopText()
  440.                                         local mapName = tostring(g_SToptimesManager.mapTimes.mapName)
  441.     --accountname = getAccountName (getPlayerAccount(player))
  442.     --if isObjectInACLGroup ( "user." .. accountname, aclGetGroup ( "Admin" ) ) then
  443.                                         local placeText = place and " #" .. tostring(place) or ""
  444.                                         outputChatBox( "#FF6464[TT] #FFFFFF"..placeText.." #FFFFFF" .. tostring(oldname) .. "#FFFFFF renamed to #FFFFFF" .. tostring(newName) .. " #FFFFFFby " .. getPlayerName(player),getRootElement(), 255,55,0,true)
  445.         else
  446.         outputChatBox("TEST!",thePlayer,255,125,0,true)
  447.                                         outputServerLog( "INFO: Top time"..placeText.." from '" ..tostring(oldname).. "' (" ..tostring(row.timeText).. " in " ..mapName.. ") renamed by " .. getAdminNameForLog(player).." to '" .. tostring(newName).."'"  )
  448.                                 end
  449.                         end
  450.                 end
  451.         end
  452.    --end
  453. )
  454.  
  455.  
  456. ---------------------------------------------------------------------------
  457. --
  458. -- Settings
  459. --
  460. --
  461. --
  462. ---------------------------------------------------------------------------
  463. function cacheSettings()
  464.         g_Settings = {}
  465.         g_Settings.numtimes             = getNumber('numtimes',8)
  466.         g_Settings.startshow    = getBool('startshow',false)
  467.         g_Settings.gui_x                = getNumber('gui_x',0.56)
  468.         g_Settings.gui_y                = getNumber('gui_y',0.02)
  469.         g_Settings.admingroup   = getString("admingroup","Admin")
  470. end
  471.  
  472. -- React to admin panel changes
  473. addEvent ( "onSettingChange" )
  474. addEventHandler('onSettingChange', g_ResRoot,
  475.         function(name, oldvalue, value, playeradmin)
  476.                 outputDebug( 'MISC', 'Setting changed: ' .. tostring(name) .. '  value:' .. tostring(value) .. '  value:' .. tostring(oldvalue).. '  by:' .. tostring(player and getPlayerName(player) or 'n/a') )
  477.                 cacheSettings()
  478.                 -- Update here
  479.                 if g_SToptimesManager then
  480.                         g_SToptimesManager.displayTopCount = g_Settings.numtimes
  481.                         g_SToptimesManager:updateTopText()
  482.                 end
  483.                 -- Update clients
  484.                 clientCall(g_Root,'updateSettings', g_Settings, playeradmin)
  485.         end
  486. )
  487.  
  488. -- New player joined
  489. addEvent('onLoadedAtClient_tt', true)
  490. addEventHandler('onLoadedAtClient_tt', g_Root,
  491.         function()
  492.                 -- Tell newly joined client current settings
  493.                 clientCall(source,'updateSettings', g_Settings)
  494.  
  495.                 -- This could also be the toptimes resource being restarted, so send some mapinfo
  496.                 local raceInfo = getRaceInfo()
  497.                 if raceInfo then
  498.                     triggerClientEvent('onClientSetMapName', source, raceInfo.mapInfo.name )
  499.                 end
  500.         end
  501. )
  502.  
  503.  
  504. ---------------------------------------------------------------------------
  505. -- Global instance
  506. ---------------------------------------------------------------------------
  507. g_SToptimesManager = SToptimesManager:create()
  508.  
  509. --------------------
  510. --Team Colors Nick--
  511. --------------------
  512.  
  513. function getPlayerTeamColoredNick(player)
  514.         local playerTeam = getPlayerTeam ( player )
  515.         if ( playerTeam ) then
  516.                 local r,g,b = getTeamColor ( playerTeam )
  517.                 local n1 = toHex(r)
  518.                 local n2 = toHex(g)
  519.                 local n3 = toHex(b)
  520.                 if r <= 16 then n1 = "0"..n1 end
  521.                 if g <= 16 then n2 = "0"..n2 end
  522.                 if b <= 16 then n3 = "0"..n3 end
  523.                 return "#"..n1..""..n2..""..n3..""..getPlayerNametagText(player)
  524.         else
  525.                 return getPlayerNametagText(player)
  526.         end
  527. end
  528.  
  529. function toHex ( n )
  530.     local hexnums = {"0","1","2","3","4","5","6","7",
  531.                      "8","9","A","B","C","D","E","F"}
  532.     local str,r = "",n%16
  533.     if n-r == 0 then str = hexnums[r+1]
  534.     else str = toHex((n-r)/16)..hexnums[r+1] end
  535.     return str
  536. end
  537.  
  538.  
  539. function someoneReachedHunter(number, sort, model)
  540.     if (sort == "vehiclechange" and model == 425) then
  541.         triggerClientEvent(source,"setSkyColor",source)
  542.         setTimer(outputChatBox,50,1,'#E26161[HUNTER]:#ffffffHunter Has Reached Sky #abcdefChanged#ffffff!', root, 255, 100, 100, true)
  543.     end
  544. end
  545. addEvent("onPlayerPickUpRacePickup",true)
  546. addEventHandler("onPlayerPickUpRacePickup",getRootElement(),someoneReachedHunter)