-
Posts
730 -
Joined
-
Last visited
-
Days Won
2
Everything posted by koragg
-
Try this, maybe @StormFighter is right about the player not being created so early. function onPlayerJoin() setTimer(function(source) fadeCamera(source, true) setElementFrozen(source, true) setCameraTarget(source, source) randomSpawn(source, randomSpawnTable) end, 1000, 1, source) end addEventHandler("onPlayerJoin", root, onPlayerJoin) function onPlayerLogin() setElementFrozen(source, false) end addEventHandler("onPlayerLogin", root, onPlayerLogin) Experiment with the timer's duration a bit, if this^ does nothing, try setting it from 1000ms to 10000ms (from 1second to 10 seconds) just to see if it will do anything when the player has for sure been created.
-
I can safely say that setElementData is no performance killer or anything. My server has 90 resources running and whenever I needed to send data from server to client (or vice versa) I used element data. And the (little xd) players that have played there didn't experience any lag from element data (if they did, their pc laptop was a potato and couldn't handle a few resources, nothing to do with element data). @pa3ck Actually I think that using triggers should theoretically be a bigger performance killer because with element data you send it once and then any resource can use it, but with events - you need to send the data separately to each resource that needs it. But the difference should be unnoticable for the normal player so it's the same which one you choose to use, be it element data or events.
-
From what I understand he means that there is a sound only when two specific players win. For example: there are players with nicks "David", "Mike" and "Robert". The sound plays only when "Mike" or "Robert" win, but when "David" wins there is no sound.
-
You can take a look at how it's done here: https://github.com/JarnoVgr/Mr.Green-MTA-Resources/tree/master/resources/[web]/interchat
-
There is an option in the scoreboard's settings in admin panel called "Allow colorcoded names" which makes color codes into actual colors when it's set to "true". So if a player has a nickname such as "#FF0000Mike" it will show up in the scoreboard as "Mike". PS: Just saw it's a custom scoreboard. Maybe try this at line 6: { name = "Nick", width = 160, data = function (element) return getPlayerName ( element ):gsub( '#%x%x%x%x%x%x', '' ) end },
-
Yep that's what i meant I will try out what you said when i get some free time. I used onClientRender because i wanted it to be as accurate as possible but i see it's not really needed.
- 10 replies
-
- distancebycar
- distancebybike
- (and 4 more)
-
Ops, made a small typo and can't edit my previous post :\ The total distance needs to be set to 0 after the event gets triggered so: totalAircraft_km = totalAircraft_km + 1 triggerServerEvent("distanceByAircraft", localPlayer, totalAircraft_km) totalAircraft_km = 0 And like that^ for each vehicle category (totalCar_km = 0, totalBike_km = 0, etc.) Otherwise it recorded huge numbers as passed KMh
- 10 replies
-
- distancebycar
- distancebybike
- (and 4 more)
-
Thanks to both of you, I used @Simple01's code as I did something similar when recording total drift score some time ago and was more familiar with it being client side. 1. Recorded the distance client-side 2. Sent it to server-side with events (those things are priceless) Client: -- Used to record distance passed with the specific vehicle category. local totalAircraft_km = 0 local partialAircraft_km = 0 local tickAircraft_km = 0 local totalBoat_km = 0 local partialBoat_km = 0 local tickBoat_km = 0 local totalBike_km = 0 local partialBike_km = 0 local tickBike_km = 0 local totalCar_km = 0 local partialCar_km = 0 local tickCar_km = 0 local totalBicycle_km = 0 local partialBicycle_km = 0 local tickBicycle_km = 0 function handleSpeed() local car = getPedOccupiedVehicle(localPlayer) local id if car then id = getElementModel(car) end -- distanceByAircraft if id == 592 or id == 577 or id == 511 or id == 512 or id == 593 or id == 520 or id == 553 or id == 476 or id == 519 or id == 460 or id == 513 or id == 548 or id == 425 or id == 417 or id == 487 or id == 488 or id == 497 or id == 563 or id == 447 or id == 469 then if car and getVehicleOccupant(car, 0) == localPlayer then if tickAircraft_km <= 0 and getVehicleEngineState(car) then tickAircraft_km = getTickCount() end if getTickCount() - tickAircraft_km >= 1000 then local sx, sy, sz = getElementVelocity(car) local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650 if partialAircraft_km + kms >= 1 then partialAircraft_km = partialAircraft_km + kms - 1 totalAircraft_km = totalAircraft_km + 1 triggerServerEvent("distanceByAircraft", localPlayer, totalAircraft_km) else partialAircraft_km = partialAircraft_km + kms end tickAircraft_km = getTickCount() end end -- distanceByBoat elseif id == 472 or id == 473 or id == 493 or id == 595 or id == 484 or id == 430 or id == 453 or id == 452 or id == 446 or id == 454 then if car and getVehicleOccupant(car, 0) == localPlayer then if tickBoat_km <= 0 and getVehicleEngineState(car) then tickBoat_km = getTickCount() end if getTickCount() - tickBoat_km >= 1000 then local sx, sy, sz = getElementVelocity(car) local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650 if partialBoat_km + kms >= 1 then partialBoat_km = partialBoat_km + kms - 1 totalBoat_km = totalBoat_km + 1 triggerServerEvent("distanceByBoat", localPlayer, totalBoat_km) else partialBoat_km = partialBoat_km + kms end tickBoat_km = getTickCount() end end -- distanceByBike elseif id == 581 or id == 509 or id == 481 or id == 462 or id == 521 or id == 463 or id == 510 or id == 522 or id == 461 or id == 448 or id == 468 or id == 586 then if car and getVehicleOccupant(car, 0) == localPlayer then if tickBike_km <= 0 and getVehicleEngineState(car) then tickBike_km = getTickCount() end if getTickCount() - tickBike_km >= 1000 then local sx, sy, sz = getElementVelocity(car) local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650 if partialBike_km + kms >= 1 then partialBike_km = partialBike_km + kms - 1 totalBike_km = totalBike_km + 1 triggerServerEvent("distanceByBike", localPlayer, totalBike_km) else partialBike_km = partialBike_km + kms end tickBike_km = getTickCount() end end -- distanceByCar elseif id == 602 or id == 496 or id == 401 or id == 518 or id == 527 or id == 589 or id == 419 or id == 587 or id == 533 or id == 526 or id == 474 or id == 545 or id == 517 or id == 410 or id == 600 or id == 436 or id == 439 or id == 549 or id == 491 or id == 485 or id == 431 or id == 438 or id == 437 or id == 574 or id == 420 or id == 525 or id == 408 or id == 552 or id == 416 or id == 433 or id == 427 or id == 490 or id == 528 or id == 407 or id == 544 or id == 523 or id == 470 or id == 596 or id == 598 or id == 599 or id == 597 or id == 432 or id == 601 or id == 428 or id == 499 or id == 609 or id == 498 or id == 524 or id == 532 or id == 578 or id == 486 or id == 406 or id == 573 or id == 455 or id == 588 or id == 403 or id == 423 or id == 414 or id == 443 or id == 515 or id == 514 or id == 531 or id == 456 or id == 459 or id == 422 or id == 482 or id == 605 or id == 530 or id == 418 or id == 572 or id == 582 or id == 413 or id == 440 or id == 543 or id == 583 or id == 478 or id == 554 or id == 579 or id == 400 or id == 404 or id == 489 or id == 505 or id == 479 or id == 442 or id == 458 or id == 536 or id == 575 or id == 534 or id == 567 or id == 535 or id == 576 or id == 412 or id == 402 or id == 542 or id == 603 or id == 475 or id == 429 or id == 541 or id == 415 or id == 480 or id == 562 or id == 565 or id == 434 or id == 494 or id == 502 or id == 503 or id == 411 or id == 559 or id == 561 or id == 560 or id == 506 or id == 451 or id == 558 or id == 555 or id == 477 or id == 441 or id == 464 or id == 594 or id == 501 or id == 465 or id == 564 or id == 606 or id == 607 or id == 610 or id == 584 or id == 611 or id == 608 or id == 435 or id == 450 or id == 591 or id == 590 or id == 538 or id == 570 or id == 569 or id == 537 or id == 449 or id == 568 or id == 424 or id == 504 or id == 457 or id == 483 or id == 508 or id == 571 or id == 500 or id == 444 or id == 556 or id == 557 or id == 471 or id == 495 or id == 539 then if car and getVehicleOccupant(car, 0) == localPlayer then if tickCar_km <= 0 and getVehicleEngineState(car) then tickCar_km = getTickCount() end if getTickCount() - tickCar_km >= 1000 then local sx, sy, sz = getElementVelocity(car) local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650 if partialCar_km + kms >= 1 then partialCar_km = partialCar_km + kms - 1 totalCar_km = totalCar_km + 1 triggerServerEvent("distanceByCar", localPlayer, totalCar_km) else partialCar_km = partialCar_km + kms end tickCar_km = getTickCount() end end -- distanceByBicycle elseif id == 509 or id == 481 or id == 510 then if car and getVehicleOccupant(car, 0) == localPlayer then if tickBicycle_km <= 0 and getVehicleEngineState(car) then tickBicycle_km = getTickCount() end if getTickCount() - tickBicycle_km >= 1000 then local sx, sy, sz = getElementVelocity(car) local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650 if partialBicycle_km + kms >= 1 then partialBicycle_km = partialBicycle_km + kms - 1 totalBicycle_km = totalBicycle_km + 1 triggerServerEvent("distanceByBicycle", localPlayer, totalBicycle_km) else partialBicycle_km = partialBicycle_km + kms end tickBicycle_km = getTickCount() end end end end addEventHandler("onClientRender", root, handleSpeed) Server: -- distanceByAircraft addEvent("distanceByAircraft", true) function distanceByAircraft(currentDistance) local playeraccount = getPlayerAccount(source) if isGuestAccount(playeraccount) then return end local prevDistance = tonumber(getAccountData(playeraccount, "distanceByAircraft") or 0) local newDistance = prevDistance + tonumber(currentDistance) setAccountData(playeraccount, "distanceByAircraft", newDistance) setElementData(source, "distanceByAircraft", newDistance) end addEventHandler("distanceByAircraft", root, distanceByAircraft) -- distanceByBoat addEvent("distanceByBoat", true) function distanceByBoat(currentDistance) local playeraccount = getPlayerAccount(source) if isGuestAccount(playeraccount) then return end local prevDistance = tonumber(getAccountData(playeraccount, "distanceByBoat") or 0) local newDistance = prevDistance + tonumber(currentDistance) setAccountData(playeraccount, "distanceByBoat", newDistance) setElementData(source, "distanceByBoat", newDistance) end addEventHandler("distanceByBoat", root, distanceByBoat) -- distanceByBike addEvent("distanceByBike", true) function distanceByBike(currentDistance) local playeraccount = getPlayerAccount(source) if isGuestAccount(playeraccount) then return end local prevDistance = tonumber(getAccountData(playeraccount, "distanceByBike") or 0) local newDistance = prevDistance + tonumber(currentDistance) setAccountData(playeraccount, "distanceByBike", newDistance) setElementData(source, "distanceByBike", newDistance) end addEventHandler("distanceByBike", root, distanceByBike) -- distanceByCar addEvent("distanceByCar", true) function distanceByCar(currentDistance) local playeraccount = getPlayerAccount(source) if isGuestAccount(playeraccount) then return end local prevDistance = tonumber(getAccountData(playeraccount, "distanceByCar") or 0) local newDistance = prevDistance + tonumber(currentDistance) setAccountData(playeraccount, "distanceByCar", newDistance) setElementData(source, "distanceByCar", newDistance) end addEventHandler("distanceByCar", root, distanceByCar) -- distanceByBicycle addEvent("distanceByBicycle", true) function distanceByBicycle(currentDistance) local playeraccount = getPlayerAccount(source) if isGuestAccount(playeraccount) then return end local prevDistance = tonumber(getAccountData(playeraccount, "distanceByBicycle") or 0) local newDistance = prevDistance + tonumber(currentDistance) setAccountData(playeraccount, "distanceByBicycle", newDistance) setElementData(source, "distanceByBicycle", newDistance) end addEventHandler("distanceByBicycle", root, distanceByCar) And then used the element data to show the correct info on the GUI. PS: I'm pretty sure I could have avoided like 70% of the code as it's the same but I prefer to play it safe
- 10 replies
-
- 1
-
- distancebycar
- distancebybike
- (and 4 more)
-
I guess that's server-side right? And I'll be able to check if it's a car, bike, etc by doing an "if getElementModel(vehElement) == 411 then". Timer set to 50 sounds the most accurate.
- 10 replies
-
- distancebycar
- distancebybike
- (and 4 more)
-
Hello people. Few days ago I started creating a new PlayerStats panel mainly focused on racing. I added the following things so far and they all work perfectly: -Cars destroyed -Bikes destroyed -Boats destroyed -Planes & Helicopters destroyed -Race starts -Race finishes -Race wins -Toptimes set -Checkpoints collected -Total earnings -Money spent -Current balance But I also wanted to add these things: *Distance travelled by car *Distance travelled by motorbike *Distance travelled by boat *Distance travelled by aircraft *Distance travelled by bicycle So my question is, how can I record the distance travelled and save it as account data like all other stats above? I saw this and although I found the code responsible for recording the distance it's done in a pretty hard way (at least for me). Is there an easy way to record distance travelled by each of the above vehicles (in KMh)?
- 10 replies
-
- distancebycar
- distancebybike
- (and 4 more)
-
Guidelines and formatting for this section [READ BEFORE POSTING]
koragg replied to Dutchman101's topic in Scripting
Finally something is being done about this. Since a few weeks ago, whenever I joined the scripting section there were pages (and no I'm not overreacting) filled with random questions, barely understandable text (there are language specific sub-forums so that's no excuse) and zero information on what the problem is, nor an effort from the poster's part. All that just made me close the tab and ignore all posts despite my original will to read a few topics and try to help. Hopefully these new rules would be obeyed. -
I'm curious why this doesn't work. I wasted lots of time trying to fix a function i made some time ago until i realized that the "test" command never works.
-
I gotta say that song is awesome I get the following message exactly after I start the map from the admin panel: ERROR: [gamemodes]\[race]\race\race_server.lua:74: attempt to concatenate field 'modename' (a nil value) I tried other DD maps but still the same error happened. It has trouble getting the 'g_MapInfo.modename' as that's where the error happens (outputDebugString('Loaded race mode ' .. g_MapInfo.modename .. ' ' .. getResourceName(mapres))). I honestly thought that DD maps should work in the default race gamemode but seems like you have to modify something to get it fixed. I'm only a race guy (no DD, DM, etc...) so that's all from me, hope somebody can help you out. PS: I actually had a few DD maps before but they were specifically designed for the server whose gamemode I'm using (it's opensource).
-
A stupid question but are you sure that you've started race gamemode :')? /start race And stop all other gamemodes before starting it.
-
I haven't looked at any tutorials as my first encounter with the executeSQLQuery was a big disaster. I needed a cash script for my server so i downloaded "mwrpanel". It saved cash to player nickname, not account. You can guess how useless that was so i asked a friend how to fix it and he said with account data. Since then i make everything at my server with account data and convert sql scripts to use account data instead (i had a sql nick protection but made this^ myself so that it uses account data and i know 100% how it works).
-
Make sure that maps are on normal folders or zip files. Folder with name "ddmap1" is ok while "[ddmap1]" isn't. Also say if there are any errors in /debugscript 3.
-
Yea well I'm doing everything with account data because i can't use sql too hard
-
Well it worked I may have confused it with setElementData if it works both ways heh
-
I decided to make a nickname locking script today for my server and it all works perfectly except a very small typo bug that I can't fix (I don't know why, I've fixed it this way before and there were no issues). So below is the script and the problem is that if there is no nickname saved to my account and I type /protected it says "Your currently protected nick is nil." in chat while it should say the appropriate line in the 'else' condition which is "You haven't protected any nickname yet.". That's at lines 49-60. Any idea why it still thinks there is account data when I already set it to 'nil'? And I thought that if I want to remove data and free the space used by it, I should indeed use 'nil' so dunno what's wrong with this script. It has worked a lot of times before. local nickTimer local joinTimer ------------------------------------------------------------------------------------------------------------------------- function lockNick(player, command, name) local nick local account = getPlayerAccount(player) if isGuestAccount(account) then outputChatBox("You need to register and login in order to protect a nickname!", player, 255, 153, 0, true) return end if not name then nick = getPlayerName(player):gsub('#%x%x%x%x%x%x', '') setAccountData(account, "protectedNick", nick) else nick = name:gsub('#%x%x%x%x%x%x', '') setAccountData(account, "protectedNick", nick) end outputChatBox("You successfully protected nickname #FFFFFF"..nick.." #00FF00to your account.", player, 0, 255, 0, true) end addCommandHandler("protect", lockNick) ------------------------------------------------------------------------------------------------------------------------- function unlockNick(player, command, name) local nick local account = getPlayerAccount(player) if isGuestAccount(account) then outputChatBox("You need to register and login in order to unprotect a nickname!", player, 255, 153, 0, true) return end if not name then nick = getPlayerName(player):gsub('#%x%x%x%x%x%x', '') if nick == getAccountData(account, "protectedNick"):gsub('#%x%x%x%x%x%x', '') then setAccountData(account, "protectedNick", nil) outputChatBox("You successfully unprotected nickname #FFFFFF"..nick.." #00FF00from your account.", player, 0, 255, 0, true) else outputChatBox("No such nickname found in the database.", player, 255, 0, 0, true) end else nick = name:gsub('#%x%x%x%x%x%x', '') if nick == getAccountData(account, "protectedNick"):gsub('#%x%x%x%x%x%x', '') then setAccountData(account, "protectedNick", nil) outputChatBox("You successfully unprotected nickname #FFFFFF"..nick.." #00FF00from your account.", player, 0, 255, 0, true) else outputChatBox("No such nickname found in the database.", player, 255, 0, 0, true) end end end addCommandHandler("unprotect", unlockNick) ------------------------------------------------------------------------------------------------------------------------- function checkProtectedNicks(player) local account = getPlayerAccount(player) if isGuestAccount(account) then return end if getAccountData(account, "protectedNick") then outputChatBox("#32CD32Your currently protected nick is #FFFFFF"..getAccountData(account, "protectedNick").."#32CD32.", player, 255, 255, 255, true) else outputChatBox("#CD5C5CYou haven't protected any nickname yet.", player, 255, 255, 255, true) end end addCommandHandler("protected", checkProtectedNicks) ------------------------------------------------------------------------------------------------------------------------- function onNickChange(oldNick, newNick) local account = getPlayerAccount(source) local allAccounts = getAccounts() for k, v in ipairs(allAccounts) do if v ~= account then if getAccountData(v, "protectedNick") and newNick:gsub('#%x%x%x%x%x%x', '') == getAccountData(v, "protectedNick"):gsub('#%x%x%x%x%x%x', '') then setTimer(function(player) changeNickToRandom(player) outputChatBox("#CD5C5CYour nick was changed to a random one because you used a protected nick.", player, 255, 255, 255, true) end, 1000, 1, source) elseif getAccountData(v, "protectedNick") and newNick:gsub('#%x%x%x%x%x%x', '') ~= getAccountData(v, "protectedNick"):gsub('#%x%x%x%x%x%x', '') then if isTimer(nickTimer) then killTimer(nickTimer) end end end end if getAccountData(account, "protectedNick") and newNick:gsub('#%x%x%x%x%x%x', '') == getAccountData(account, "protectedNick"):gsub('#%x%x%x%x%x%x', '') then if isTimer(nickTimer) then killTimer(nickTimer) end outputChatBox("#32CD32You are allowed to use this protected nick.", source, 255, 255, 255, true) end end addEventHandler("onPlayerChangeNick", root, onNickChange) ------------------------------------------------------------------------------------------------------------------------- function onPlayerJoin() joinTimer = setTimer(function(player) local account = getPlayerAccount(player) local allAccounts = getAccounts() local currentNick = getPlayerName(player):gsub('#%x%x%x%x%x%x', '') if not isGuestAccount(account) then local nickData = getAccountData(account, "protectedNick"):gsub('#%x%x%x%x%x%x', '') if currentNick == nickData then outputChatBox("#32CD32You are now allowed to use this protected nick.", player, 255, 255, 255, true) return end else for k, v in ipairs(allAccounts) do if getAccountData(v, "protectedNick") and currentNick == getAccountData(v, "protectedNick"):gsub('#%x%x%x%x%x%x', '') then outputChatBox("#CD5C5CYour nick #FFFFFF"..getAccountData(v, "protectedNick"):gsub('#%x%x%x%x%x%x', '').." #CD5C5Cis protected. Please login or change nick within 60 seconds.", player, 255, 255, 255, true) if isTimer(nickTimer) then killTimer(nickTimer) end nickTimer = setTimer(function(player) changeNickToRandom(player) outputChatBox("#CD5C5CYour nick was changed to a random one because you used a protected nick.", player, 255, 255, 255, true) end, 60000, 1, player) end end end end, 10000, 1, source) end addEventHandler("onPlayerJoin", root, onPlayerJoin) ------------------------------------------------------------------------------------------------------------------------- function onPlayerLogin() local account = getPlayerAccount(source) local currentNick = getPlayerName(source):gsub('#%x%x%x%x%x%x', '') local nickData = getAccountData(account, "protectedNick"):gsub('#%x%x%x%x%x%x', '') local lockedNick local allAccounts = getAccounts() for k, v in ipairs(allAccounts) do if v ~= account then lockedNick = getAccountData(v, "protectedNick") end end if nickData and currentNick == nickData then if isTimer(nickTimer) then killTimer(nickTimer) end if isTimer(joinTimer) then return end outputChatBox("#32CD32You are now allowed to use this protected nick.", source, 255, 255, 255, true) return elseif lockedNick and currentNick == lockedNick then changeNickToRandom(source) outputChatBox("#CD5C5CYour nick was changed to a random one because you used a protected nick.", source, 255, 255, 255, true) end end addEventHandler("onPlayerLogin", root, onPlayerLogin) ------------------------------------------------------------------------------------------------------------------------- function onPlayerLogout() local account = getPlayerAccount(source) local curName = getPlayerName(source):gsub('#%x%x%x%x%x%x', '') local allAccounts = getAccounts() if isGuestAccount(account) then for k, v in ipairs(allAccounts) do if getAccountData(v, "protectedNick") and curName == getAccountData(v, "protectedNick") then changeNickToRandom(source) outputChatBox("#CD5C5CYour nick was changed to a random one because you used a protected nick.", source, 255, 255, 255, true) end end end end addEventHandler("onPlayerLogout", root, onPlayerLogout) ------------------------------------------------------------------------------------------------------------------------- function changeNickToRandom(player) local randomNick = "Guest"..math.random(100000000,999999999) while getPlayerFromName(randomNick) do randomNick = "Guest"..math.random(100000000,999999999) end setPlayerName(player, randomNick) end ------------------------------------------------------------------------------------------------------------------------- function adminRemoveNick(player, command, name) local account = getPlayerAccount(player) local accountName = getAccountName(account) if isGuestAccount(account) then return end if isObjectInACLGroup("user."..accountName, aclGetGroup("Admin")) or isObjectInACLGroup("user."..accountName, aclGetGroup("SuperModerator")) then if not name then outputChatBox("#FF0000Correct command is : #FEFE22/freenick [full nick]", player, 0, 255, 0, true) return end local allAccounts = getAccounts() for k, v in ipairs(allAccounts) do if getAccountData(v, "protectedNick") then if string.lower(getAccountData(v, "protectedNick"):gsub('#%x%x%x%x%x%x', '')) == string.lower(name:gsub('#%x%x%x%x%x%x', '')) then outputChatBox("#32CD32You successfully unlocked nick #FFFFFF"..getAccountData(v, "protectedNick").."#32CD32.", player, 255, 255, 255, true) setAccountData(v, "protectedNick", nil) else outputChatBox("No such nickname is saved in the database.", player, 255, 0, 0, true) end end end end end addCommandHandler("freenick", adminRemoveNick)
-
Well, hope someone sees this topic and helps. Anyway, thanks for trying.
-
function SToptimesManager:updateTopText() if not self.mapTimes then return end -- Update data -- Read top rows from map toptimes table and send to all players who want to know self.toptimesDataForMap = self.mapTimes:getToptimes( self.displayTopCount ) self.serverRevision = self.serverRevision + 1 -- Queue send to all players for i,player in ipairs(self.playersWhoWantUpdates) do self:queueUpdate(player) end end As you can see it's linked with 1000 other things...
-
Yes both if statements work fine. Also fixed the ghost files. It should have been ":raceghost/ghosts" and not "raceghost/ghosts". But the display update is acting weird. Below code is all in race_toptimes/toptimes_server.lua file. Then I just use 'executeCommandHandler("updatetops", player)' to use it in my resource. --Used in the "deltops" resource to update current map's tops display after all of the tops of a player are deleted. function triggerCurrentMapTopsUpdate(player) local accountName = getAccountName(getPlayerAccount(player)) if isObjectInACLGroup("user."..accountName, aclGetGroup("Admin")) or isObjectInACLGroup("user."..accountName, aclGetGroup("SuperModerator")) then outputChatBox("1") if g_SToptimesManager and g_SToptimesManager.mapTimes then local row = g_SToptimesManager.mapTimes:deletetime() if row then g_SToptimesManager:updateTopText() end end outputChatBox("3") outputChatBox("2") end end addCommandHandler("updatetops", triggerCurrentMapTopsUpdate) If I remove lines 6, 7, 8, 10 and 11 it does not update. But if I keep it like that^ it updates. There's just one problem. Line 7 deletes the top1 on a map so it ruins everything. Why can't I just use the function on line 9 without first being forced to delete the top1 on current map (again, this ruins everything). I only want to update the display, not delete things. But it won't let me update it unless I delete top1, wtf? This is the last thing that's left to fix, evertything else works perfectly now.
-
@pa3ck if I put a chat msg after line 33 it shows, but the one after line 34 doesn't. Also when I check both values they show normally. I found the problem It isn't really a problem with the script/syntax/logic. If you look at the code I sent above you'll see that I first delete the toptimes and then try to compare them with the written nickname (I'm comparing the written nick with top1s which will never be same as it, because I've already deleted that top1 nickname earlier in the code). So now it works, but ghosts don't get deleted. if fileExists("raceghost/ghosts/"..getResourceName(map_names[mapTable])..".ghost") then fileDelete("raceghost/ghosts/"..getResourceName(map_names[mapTable])..".ghost") end The path is correct and the ghost file names are the map's folder name (aka getResourceName) so why aren't ghost files being deleted? Full code below: function delAllTopsOfPlayer(player, command, name) local accountName = getAccountName(getPlayerAccount(player)) if isGuestAccount (getPlayerAccount(player)) or not (isObjectInACLGroup("user."..accountName, aclGetGroup("Admin")) or isObjectInACLGroup("user."..accountName, aclGetGroup("SuperModerator"))) then return end if not name then outputChatBox("You must specify a player name in order to delete all of their toptimes!", player, 255, 0, 0, true) return end local otherPlayer = string.lower(name) local otherPlayerName local map_names = {} for k, v in ipairs(exports.mapmanager:getMapsCompatibleWithGamemode(getResourceFromName('race'))) do local rname = getResourceName(v) local mode = 'Sprint' map_names['race maptimes '..mode..' ' .. (getResourceInfo(v, 'name' ) or getResourceName(v))] = v end local maps_table = executeSQLQuery("SELECT tbl_name FROM sqlite_master WHERE tbl_name LIKE 'race maptimes %' ") for k, v in ipairs(maps_table) do local mapTable = v.tbl_name if map_names[mapTable] then local mapTimes = executeSQLQuery("SELECT playerName FROM ?", mapTable) for i, t in ipairs(mapTimes) do if getAccount(t.playerName) then if string.lower(getAccountData(getAccount(t.playerName), "currentPlayerName"):gsub('#%x%x%x%x%x%x', '')) == otherPlayer:gsub('#%x%x%x%x%x%x', '') then otherPlayerName = getAccountData(getAccount(t.playerName), "currentPlayerName") local topsTable = getModeAndMap('Sprint', getResourceInfo(map_names[mapTable], 'name')) local topsSql = executeSQLQuery('SELECT playerName AS topName FROM '..qsafetablename(topsTable)) if type(topsSql) == 'table' and #topsSql > 0 then if topsSql[1] then if getAccount(topsSql[1].topName) then if string.lower(getAccountData(getAccount(topsSql[1].topName), "currentPlayerName"):gsub('#%x%x%x%x%x%x', '')) == otherPlayer:gsub('#%x%x%x%x%x%x', '') then local delays = executeSQLQuery("SELECT * FROM mapinterims WHERE mapname = ?", getResourceName(map_names[mapTable])) if delays and #delays > 0 then executeSQLQuery("DELETE FROM mapinterims WHERE mapname=?", getResourceName(map_names[mapTable])) end if fileExists("raceghost/ghosts/"..getResourceName(map_names[mapTable])..".ghost") then fileDelete("raceghost/ghosts/"..getResourceName(map_names[mapTable])..".ghost") end end end end end executeSQLQuery("DELETE FROM ? WHERE playerName=?", mapTable, t.playerName) end end end end end if otherPlayerName then outputChatBox("#FF0000All of #FFFFFF"..otherPlayerName.."#FF0000's toptimes were deleted!" , root, 255, 0, 0, true) outputServerLog("Toptimes of "..otherPlayerName:gsub('#%x%x%x%x%x%x', '').." deleted!") outputServerLog("Delay times of "..otherPlayerName:gsub('#%x%x%x%x%x%x', '').." deleted!") outputServerLog("Ghost records of "..otherPlayerName:gsub('#%x%x%x%x%x%x', '').." deleted!") else outputChatBox("No such player name found in toptimes database.", player, 255, 0, 0, true) end end addCommandHandler("deletealltimes", delAllTopsOfPlayer) addCommandHandler("deletealltops", delAllTopsOfPlayer) addCommandHandler("delalltimes", delAllTopsOfPlayer) addCommandHandler("delalltops", delAllTopsOfPlayer) ------------------------------------------------------------------------------------------------------------------------- function getModeAndMap(gMode, mapName) return 'race maptimes '..gMode..' '..mapName end ------------------------------------------------------------------------------------------------------------------------- function qsafetablename(s) return qsafestring(s) end ------------------------------------------------------------------------------------------------------------------------- function qsafestring(s) return "'"..safestring(s).."'" end ------------------------------------------------------------------------------------------------------------------------- function safestring(s) return s:gsub("(['])", "''") end PS: When I delete all toptimes of a player, the table updates on new map start. Any way to make it update the toptimes display the moment it finishes deleting tops of the specified player? Example: 1. Brian 2. Mia 3. Dom I do /delalltops Mia It shows that they're deleted (and they are) but in the toptimes display window in F5 Mia is still at #2 because the display has not yet updated. I think this can cause trouble if someone else does a top but the one before it was deleted yet is still displayed.
-
So I tried this and I don't know where the problem can be: function delAllTopsOfPlayer(player, command, name) local accountName = getAccountName(getPlayerAccount(player)) if isGuestAccount (getPlayerAccount(player)) or not (isObjectInACLGroup("user."..accountName, aclGetGroup("Admin")) or isObjectInACLGroup("user."..accountName, aclGetGroup("SuperModerator"))) then return end if not name then outputChatBox("You must specify a player name in order to delete all of their toptimes!", player, 255, 0, 0, true) return end local otherPlayer = string.lower(name) local otherPlayerName local top1Nick local map_names = {} for k, v in ipairs(exports.mapmanager:getMapsCompatibleWithGamemode(getResourceFromName('race'))) do local rname = getResourceName(v) local mode = 'Sprint' map_names['race maptimes '..mode..' ' .. (getResourceInfo(v, 'name' ) or getResourceName(v))] = v end local maps_table = executeSQLQuery("SELECT tbl_name FROM sqlite_master WHERE tbl_name LIKE 'race maptimes %' ") for k, v in ipairs(maps_table) do local mapTable = v.tbl_name if map_names[mapTable] then local mapTimes = executeSQLQuery("SELECT playerName FROM ?", mapTable) for i, t in ipairs(mapTimes) do if getAccount(t.playerName) then if string.lower(getAccountData(getAccount(t.playerName), "currentPlayerName"):gsub('#%x%x%x%x%x%x', '')) == otherPlayer:gsub('#%x%x%x%x%x%x', '') then otherPlayerName = getAccountData(getAccount(t.playerName), "currentPlayerName") executeSQLQuery("DELETE FROM ? WHERE playerName=?", mapTable, t.playerName) local topsTable = getModeAndMap('Sprint', getResourceInfo(map_names[mapTable], 'name')) local topsSql = executeSQLQuery('SELECT playerName AS topName FROM '..qsafetablename(topsTable)) if type(topsSql) == 'table' and #topsSql > 0 then if topsSql[1] then if getAccount(topsSql[1].topName) then if string.lower(getAccountData(getAccount(topsSql[1].topName), "currentPlayerName"):gsub('#%x%x%x%x%x%x', '')) == otherPlayer:gsub('#%x%x%x%x%x%x', '') then outputChatBox("1") local delays = executeSQLQuery("SELECT * FROM mapinterims WHERE mapname = ?", getResourceName(map_names[mapTable])) if delays and #delays > 0 then executeSQLQuery("DELETE FROM mapinterims WHERE mapname=?", getResourceName(map_names[mapTable])) end if fileExists("ghosts/"..getResourceName(map_names[mapTable])..".ghost") then fileDelete("ghosts/"..getResourceName(map_names[mapTable])..".ghost") end end end end end end end end end end if otherPlayerName then outputChatBox("#FF0000All of #FFFFFF"..otherPlayerName.."#FF0000's toptimes were deleted!" , root, 255, 0, 0, true) outputServerLog("Toptimes of "..otherPlayerName:gsub('#%x%x%x%x%x%x', '').." deleted!") outputServerLog("Delay times of "..otherPlayerName:gsub('#%x%x%x%x%x%x', '').." deleted!") outputServerLog("Ghost records of "..otherPlayerName:gsub('#%x%x%x%x%x%x', '').." deleted!") else outputChatBox("No such player name found in toptimes database.", p, 255, 0, 0, true) end end addCommandHandler("deletealltimes", delAllTopsOfPlayer) addCommandHandler("deletealltops", delAllTopsOfPlayer) addCommandHandler("delalltimes", delAllTopsOfPlayer) addCommandHandler("delalltops", delAllTopsOfPlayer) ------------------------------------------------------------------------------------------------------------------------- function getModeAndMap(gMode, mapName) return 'race maptimes '..gMode..' '..mapName end ------------------------------------------------------------------------------------------------------------------------- function qsafetablename(s) return qsafestring(s) end ------------------------------------------------------------------------------------------------------------------------- function qsafestring(s) return "'"..safestring(s).."'" end ------------------------------------------------------------------------------------------------------------------------- function safestring(s) return s:gsub("(['])", "''") end It doesn't go below line 34 for some reason. Also is that a correct way of checking if each map's top1 name is the same as the entered text? It should work but...no idea 100% something is wrong with line 34 (as the "1" doesn't show in chat) but I can't put my finger on what it is.