mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
Upload
This commit is contained in:
174
lua/chess/cl_dermaboard.lua
Normal file
174
lua/chess/cl_dermaboard.lua
Normal file
@@ -0,0 +1,174 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local PanelCol = {
|
||||
Main = Color(0,0,0,200), Hover = Color(0,255,0,50), Selected = Color(150,50,50,170),
|
||||
Move = Color(10,25,150,150), HasMoved = Color(50,50,50,100), Text = Color(0,0,0,255),
|
||||
|
||||
GridWhite = Color(255, 248, 220), GridBlack = Color(210, 180, 140),
|
||||
|
||||
White = Color(180,180,180), Black = Color(0,0,0),
|
||||
}
|
||||
-- local ColText = Color(50,50,50,200)
|
||||
-- local ColBlack,ColWhite = Color(0,0,0,120),Color(255,255,255,10)
|
||||
|
||||
local NumToLetter = {"a", "b", "c", "d", "e", "f", "g", "h", ["a"]=1, ["b"]=2, ["c"]=3, ["d"]=4, ["e"]=5, ["f"]=6, ["g"]=7, ["h"]=8} --Used extensively for conversions
|
||||
surface.CreateFont( "ChessPieces", { font = "Arial", size = 64, weight = 300})
|
||||
|
||||
function Chess_Open2DBoard( board )
|
||||
if not IsValid(board) then return end
|
||||
if IsValid( Chess_2DDermaPanel ) then Chess_2DDermaPanel:Remove() end
|
||||
|
||||
Chess_2DDermaPanel = vgui.Create( "DFrame" )
|
||||
local frame = Chess_2DDermaPanel
|
||||
frame:SetTitle( "2D Game Board" )
|
||||
frame:SetSize( 740, 760 )
|
||||
frame:SetPos( (ScrW()/2)-370, (ScrH()/2)-380 )
|
||||
frame.Paint = function( s,w,h )
|
||||
if not IsValid(board) then
|
||||
s:Remove()
|
||||
end
|
||||
|
||||
draw.RoundedBox( 8, 0, 0, w, h, PanelCol.Main )
|
||||
end
|
||||
frame:MakePopup()
|
||||
|
||||
local pnlBoard = vgui.Create( "DPanel", frame )
|
||||
pnlBoard:SetSize( 720, 720 )
|
||||
pnlBoard:SetPos(10,30)
|
||||
|
||||
pnlBoard.Squares = {}
|
||||
pnlBoard.Paint = function() end
|
||||
|
||||
local function DoTiles(swapped)
|
||||
if pnlBoard.Squares then
|
||||
for _,v in pairs(pnlBoard.Squares) do
|
||||
for _,pnl in pairs(v) do
|
||||
pnl:Remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i=0,7 do
|
||||
pnlBoard.Squares[i] = {}
|
||||
for n=0,7 do
|
||||
local pnl = vgui.Create( "DModelPanel", pnlBoard )
|
||||
pnlBoard.Squares[i][n] = pnl
|
||||
|
||||
pnl:SetPos( (swapped and 7-i or i)*90, (swapped and 7-n or n)*90 )
|
||||
pnl:SetSize(90,90)
|
||||
pnl.GridCol = (((i+n)%2)==1) and PanelCol.GridBlack or PanelCol.GridWhite
|
||||
pnl.GridPos = {i,n}
|
||||
pnl.oPaint = pnl.Paint
|
||||
pnl.Paint = function(s,w,h)
|
||||
surface.SetDrawColor( s.GridCol )
|
||||
surface.DrawRect( 0,0, w,h )
|
||||
|
||||
if not IsValid(board) then return end
|
||||
|
||||
if s:IsHovered() then
|
||||
surface.SetDrawColor( PanelCol.Hover )
|
||||
surface.DrawRect( 0,0, w,h )
|
||||
end
|
||||
if board.Selected and board.Selected[1]==s.GridPos[1] and board.Selected[2]==s.GridPos[2] then
|
||||
surface.SetDrawColor( PanelCol.Selected )
|
||||
surface.DrawRect( 0,0, w,h )
|
||||
end
|
||||
if board:GetTableGrid( board.Moves, s.GridPos[1], s.GridPos[2]) then
|
||||
surface.SetDrawColor( PanelCol.Move )
|
||||
surface.DrawRect( 0,0, w,h )
|
||||
end
|
||||
|
||||
local col,square = board.Pieces[ NumToLetter[s.GridPos[1]+1] ]
|
||||
if col then
|
||||
square = col[8-s.GridPos[2]]
|
||||
if square then
|
||||
if not (square.Team and square.Class) then return end
|
||||
|
||||
if square.Moving then
|
||||
surface.SetDrawColor( PanelCol.HasMoved )
|
||||
surface.DrawRect( 0,0, w,h )
|
||||
end
|
||||
|
||||
if board.Characters then
|
||||
draw.SimpleText( board.Characters[square.Team .. square.Class], "ChessPieces", w/2, h/2, PanelCol.Text, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
|
||||
else
|
||||
s:SetModel( board.Models[square.Team .. square.Class] )
|
||||
|
||||
return s.oPaint( s,w,h )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if cvars.Bool("chess_gridletters") then
|
||||
local str = (NumToLetter[i+1]..tostring(8-n)):upper()
|
||||
draw.SimpleText( str, "ChessTextSmall", 5, h-20, PanelCol.Black )
|
||||
end
|
||||
end
|
||||
|
||||
pnl.DoClick = function(s)
|
||||
if not IsValid(board) then return end
|
||||
|
||||
if board.Selected and board:GetTableGrid( board.Moves, pnl.GridPos[1], pnl.GridPos[2] ) then
|
||||
board:RequestMove( board.Selected[1], board.Selected[2], pnl.GridPos[1], pnl.GridPos[2] )
|
||||
board:ResetHighlights()
|
||||
elseif board.Selected and board.Selected[1]==s.GridPos[1] and board.Selected[2]==s.GridPos[2] then
|
||||
board:ResetHighlights()
|
||||
else
|
||||
board:ResetHighlights()
|
||||
board.Selected = {s.GridPos[1],s.GridPos[2]}
|
||||
board.Moves = board:GetMove( NumToLetter[s.GridPos[1]+1], 8-s.GridPos[2] )
|
||||
end
|
||||
end
|
||||
pnl.LayoutEntity = function( s, ent )
|
||||
ent:SetPos( Vector(20,20,20) )
|
||||
ent:SetAngles( Angle(0,-50,0) )
|
||||
end
|
||||
|
||||
pnl:SetModel( board.Models["WhitePawn"] )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local swap = vgui.Create( "DButton", frame )
|
||||
swap:SetImage( "icon16/arrow_rotate_clockwise.png" )
|
||||
swap:SetSize( 18,18 )
|
||||
swap:SetPos( 620,6 )
|
||||
swap:SetText( "" )
|
||||
swap.DoClick = function(s)
|
||||
s.Swapped = not s.Swapped
|
||||
DoTiles( s.Swapped )
|
||||
end
|
||||
swap.Paint = function() end
|
||||
|
||||
local toggleGridLetters = vgui.Create( "DCheckBox", frame )
|
||||
toggleGridLetters:SetImage( "icon16/font.png" )
|
||||
toggleGridLetters:SetSize( 18,18 )
|
||||
toggleGridLetters:SetPos( 600,6 )
|
||||
toggleGridLetters:SetText( "" )
|
||||
toggleGridLetters:SetConVar( "chess_gridletters" )
|
||||
toggleGridLetters.OnChange = function(s,newvalue)
|
||||
s:SetAlpha( s:GetChecked() and 255 or 100 )
|
||||
end
|
||||
toggleGridLetters.Paint = function() end
|
||||
toggleGridLetters.PerformLayout = function(s) -- DCheckBox overwrites DButton's PerformLayout, re-apply it
|
||||
if IsValid(s.m_Image) then
|
||||
s.m_Image:SetPos( 4, ( s:GetTall() - s.m_Image:GetTall() ) * 0.5 )
|
||||
s:SetTextInset( s.m_Image:GetWide() + 16, 0 )
|
||||
end
|
||||
|
||||
DLabel.PerformLayout( s )
|
||||
end
|
||||
|
||||
swap.Swapped = false
|
||||
DoTiles( swap.Swapped )
|
||||
end
|
||||
149
lua/chess/cl_top.lua
Normal file
149
lua/chess/cl_top.lua
Normal file
@@ -0,0 +1,149 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local Top10
|
||||
local function ChessTop10( typ )
|
||||
if IsValid(Top10) then Top10:Remove() end
|
||||
|
||||
typ = typ or "Chess"
|
||||
|
||||
Top10 = vgui.Create( "DFrame" )
|
||||
Top10:SetSize( 450, 245 )
|
||||
Top10:SetPos( (ScrW()/2)-150, (ScrH()/2)-100 )
|
||||
Top10:SetTitle( "Top 10 Chess Elo ratings" )
|
||||
Top10:MakePopup()
|
||||
Top10.Column = "Elo"
|
||||
|
||||
local pnl = vgui.Create("DPanel", Top10)
|
||||
pnl.Paint = function() end
|
||||
pnl:SetTall(20)
|
||||
pnl:Dock(BOTTOM)
|
||||
|
||||
Top10.Rank = vgui.Create( "DLabel", pnl )
|
||||
Top10.Rank:Dock( LEFT )
|
||||
Top10.Rank:SetTall( 20 )
|
||||
Top10.Rank:SetWide( 150 )
|
||||
Top10.Rank:SetText("")
|
||||
|
||||
Top10.Updated = vgui.Create( "DLabel", pnl )
|
||||
Top10.Updated:Dock( RIGHT )
|
||||
Top10.Updated:SetTall( 150 )
|
||||
Top10.Updated:SetText("")
|
||||
|
||||
Top10.List = vgui.Create( "DListView", Top10 )
|
||||
local List = Top10.List
|
||||
List:Dock( FILL )
|
||||
List:AddColumn( "Rank" )
|
||||
List:AddColumn( "Name" )
|
||||
List:AddColumn( "SteamID" )
|
||||
List:AddColumn( "Elo" )
|
||||
|
||||
List:AddLine( "", "Loading..." )
|
||||
-- PrintTable( List.Columns )
|
||||
List:OnRequestResize( List.Columns[1], 10 )
|
||||
List:OnRequestResize( List.Columns[2], 150 )
|
||||
List:OnRequestResize( List.Columns[3], 100 )
|
||||
List:OnRequestResize( List.Columns[4], 10 )
|
||||
|
||||
net.Start( "Chess Top10" ) net.WriteString( typ ) net.SendToServer()
|
||||
end
|
||||
local function DraughtsTop10()
|
||||
ChessTop10( "Draughts" )
|
||||
end
|
||||
concommand.Add( "chess_top", function( p,c,a ) ChessTop10() end)
|
||||
concommand.Add( "checkers_top", function( p,c,a ) DraughtsTop10() end)
|
||||
|
||||
local ChatCommands = {
|
||||
["!chess"]=ChessTop10, ["!chesstop"]=ChessTop10, ["!topchess"]=ChessTop10,
|
||||
["/chess"]=ChessTop10, ["/chesstop"]=ChessTop10, ["/topchess"]=ChessTop10,
|
||||
|
||||
["!draughts"]=DraughtsTop10, ["!draughtstop"]=DraughtsTop10, ["!topdraughts"]=DraughtsTop10,
|
||||
["/draughts"]=DraughtsTop10, ["/draughtstop"]=DraughtsTop10, ["/topdraughts"]=DraughtsTop10,
|
||||
|
||||
["!checkers"]=DraughtsTop10, ["!checkerstop"]=DraughtsTop10, ["!topcheckers"]=DraughtsTop10,
|
||||
["/checkers"]=DraughtsTop10, ["/checkerstop"]=DraughtsTop10, ["/topcheckers"]=DraughtsTop10,
|
||||
}
|
||||
hook.Add( "OnPlayerChat", "Chess Top10 PlayerChat", function( ply, str, tm, dead )
|
||||
if ChatCommands[str:lower()] then
|
||||
if ply==LocalPlayer() then
|
||||
ChatCommands[str:lower()]()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end)
|
||||
|
||||
local function SecondsToTime(num)
|
||||
if updateTime>=86400 then
|
||||
return ("%i day%s"):format( math.floor(updateTime/86400), updateTime>=172800 and "s" or "")
|
||||
elseif updateTime>=3600 then
|
||||
return ("%i hour%s"):format( math.floor(updateTime/3600), updateTime>=7200 and "s" or "")
|
||||
elseif updateTime>=60 then
|
||||
return ("%i minute%s"):format( math.floor(updateTime/60), updateTime>=120 and "s" or "")
|
||||
else
|
||||
return ("%i second%s"):format(updateTime, updateTime>=2 and "s" or "")
|
||||
end
|
||||
end
|
||||
|
||||
local lastTable = {}
|
||||
local lastRank = {}
|
||||
local lastUpdate = {}
|
||||
net.Receive( "Chess Top10", function()
|
||||
if not (IsValid(Top10) and IsValid(Top10.List)) then return end
|
||||
|
||||
Top10.List:Clear()
|
||||
|
||||
local typ = net.ReadString() or "[Error]"
|
||||
|
||||
Top10:SetTitle( "Top 10 "..typ.." Elo ratings" )
|
||||
|
||||
local tbl = net.ReadTable()
|
||||
if (not tbl) or (#tbl==0) then -- Rate limit exceeded
|
||||
if lastTable[typ] then
|
||||
for i=1,#lastTable[typ] do
|
||||
Top10.List:AddLine( tonumber(lastTable[typ][i].Rank), lastTable[typ][i].Username, lastTable[typ][i].SteamID, tonumber(lastTable[typ][i]["Elo" ]) )
|
||||
end
|
||||
Top10.Rank:SetText( "You are rank "..lastRank[typ] )
|
||||
|
||||
if lastUpdate[typ] then
|
||||
updateTime = math.floor(CurTime() - lastUpdate[typ])
|
||||
if updateTime>0 then
|
||||
Top10.Updated:SetText( ("Updated %s ago."):format(SecondsToTime(updateTime)) )
|
||||
end
|
||||
Top10.Updated:SizeToContents()
|
||||
end
|
||||
else
|
||||
Top10.List:AddLine( "", "ERROR: Rate limit exceeded." )
|
||||
Top10.List:AddLine( "", "Please try again in a few minutes." )
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
for i=1,#tbl do
|
||||
Top10.List:AddLine( tonumber(tbl[i].Rank), tbl[i].Username, tbl[i].SteamID, tonumber(tbl[i]["Elo" ]) )
|
||||
end
|
||||
|
||||
local rank = (net.ReadString() or "N/A")
|
||||
Top10.Rank:SetText( "You are rank "..rank )
|
||||
|
||||
lastUpdate[typ] = tonumber(net.ReadString())
|
||||
if lastUpdate[typ] then
|
||||
updateTime = math.floor(CurTime() - lastUpdate[typ])
|
||||
|
||||
if updateTime>0 then
|
||||
Top10.Updated:SetText( ("Updated %s ago."):format(SecondsToTime(updateTime)) )
|
||||
end
|
||||
Top10.Updated:SizeToContents()
|
||||
end
|
||||
|
||||
lastTable[typ] = tbl
|
||||
lastRank[typ] = rank
|
||||
end)
|
||||
123
lua/chess/sh_player_ext.lua
Normal file
123
lua/chess/sh_player_ext.lua
Normal file
@@ -0,0 +1,123 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local PLAYER = FindMetaTable( "Player" )
|
||||
if not PLAYER then return end
|
||||
|
||||
function PLAYER:GetChessElo()
|
||||
return self:GetNWInt( "ChessElo", 1400 ) or 1400
|
||||
end
|
||||
function PLAYER:GetDraughtsElo()
|
||||
return self:GetNWInt( "DraughtsElo", 1400 ) or 1400
|
||||
end
|
||||
if CLIENT then return end
|
||||
function PLAYER:SetChessElo( num )
|
||||
self:SetNWInt( "ChessElo", num or Chess_GetElo(ply:SteamID()) or 1400 )
|
||||
Chess_SetElo( self:SteamID(), num, false )
|
||||
end
|
||||
function PLAYER:SetDraughtsElo( num )
|
||||
self:SetNWInt( "DraughtsElo", num or Chess_GetElo(ply:SteamID(), true) or 1400 )
|
||||
Chess_SetElo( self:SteamID(), num, true )
|
||||
end
|
||||
|
||||
function PLAYER:RefreshChessElo()
|
||||
-- Convert old PData stuff
|
||||
if self:GetPData("ChessElo") then
|
||||
Chess_SetElo( self:SteamID(), self:GetPData("ChessElo"), false )
|
||||
self:RemovePData("ChessElo")
|
||||
end
|
||||
if self:GetPData("DraughtsElo") then
|
||||
Chess_SetElo( self:SteamID(), self:GetPData("DraughtsElo"), true )
|
||||
self:RemovePData("DraughtsElo")
|
||||
end
|
||||
|
||||
self:SetChessElo( Chess_GetElo(self:SteamID()) or 1400)
|
||||
self:SetDraughtsElo( Chess_GetElo(self:SteamID(), true) or 1400)
|
||||
end
|
||||
hook.Add( "PlayerInitialSpawn", "Chess InitialSpawn InitElo", function(ply)
|
||||
ply:RefreshChessElo()
|
||||
end)
|
||||
|
||||
function PLAYER:ExpectedChessWin( against )
|
||||
return (1/ (1+( 10^( (against:GetChessElo() - self:GetChessElo())/400 ) )) )
|
||||
end
|
||||
function PLAYER:ExpectedDraughtsWin( against )
|
||||
return (1/ (1+( 10^( (against:GetDraughtsElo() - self:GetDraughtsElo())/400 ) )) )
|
||||
end
|
||||
|
||||
function PLAYER:GetChessKFactor() --Imitating FIDE's K-factor ranges
|
||||
local games = tonumber(self:GetPData( "ChessGamesPlayed", 0 )) or 0
|
||||
if games<30 then
|
||||
self:SetPData( "ChessEloKFactor", 15 )
|
||||
return 30
|
||||
end
|
||||
local k = self:GetChessElo()>=2400 and 10 or self:GetPData( "ChessEloKFactor", 15 ) or 15
|
||||
self:SetPData( "ChessEloKFactor", k )
|
||||
return k
|
||||
end
|
||||
function PLAYER:GetDraughtsKFactor() --Imitating FIDE's K-factor ranges
|
||||
local games = self:GetPData( "DraughtsGamesPlayed", 0 )
|
||||
if games<30 then
|
||||
self:SetPData( "DraughtsEloKFactor", 15 )
|
||||
return 30
|
||||
end
|
||||
local k = self:GetDraughtsElo()>=2400 and 10 or self:GetPData( "DraughtsEloKFactor", 15 ) or 15
|
||||
self:SetPData( "DraughtsEloKFactor", k )
|
||||
return k
|
||||
end
|
||||
|
||||
function PLAYER:DoChessElo( score, against )
|
||||
local mod = math.ceil(self:GetChessKFactor() * (score - self:ExpectedChessWin(against)))
|
||||
local NewElo = math.floor( self:GetChessElo() + mod )
|
||||
|
||||
self:SetChessElo( NewElo )
|
||||
|
||||
if IsValid(against) then
|
||||
mod = mod*(-1)
|
||||
local NewElo = math.floor( against:GetChessElo() + mod )
|
||||
|
||||
against:SetChessElo( NewElo )
|
||||
local rank,count = Chess_GetRank(against)
|
||||
against:ChatPrint( "Your chess Elo rating changed by "..tostring(mod).." to "..tostring(NewElo).."!" ..(rank and " You are #"..tostring(rank).." on this server." or "") )
|
||||
end
|
||||
local rank,count = Chess_GetRank(self)
|
||||
self:ChatPrint( "Your chess Elo rating changed by "..tostring(mod).." to "..tostring(NewElo).."!" ..(rank and " You are #"..tostring(rank).." on this server." or "") )
|
||||
|
||||
Chess_UpdateElo( self )
|
||||
end
|
||||
function PLAYER:ChessWin( against )
|
||||
if not IsValid(against) then return end
|
||||
|
||||
self:DoChessElo(1, against)
|
||||
end
|
||||
function PLAYER:ChessDraw( against ) self:DoChessElo(0.5, against) end
|
||||
|
||||
function PLAYER:DoDraughtsElo( score, against )
|
||||
local mod = math.ceil(self:GetDraughtsKFactor() * (score - self:ExpectedDraughtsWin(against)))
|
||||
local NewElo = math.floor( self:GetDraughtsElo() + mod )
|
||||
|
||||
self:SetDraughtsElo( NewElo )
|
||||
|
||||
if IsValid(against) then
|
||||
mod = mod*(-1)
|
||||
local NewElo = math.floor( against:GetDraughtsElo() + mod )
|
||||
|
||||
against:SetDraughtsElo( NewElo )
|
||||
local rank = Chess_GetRank(self, "Draughts")
|
||||
against:ChatPrint( "Your draughts Elo rating changed by "..tostring(mod).." to "..tostring(NewElo).."!" ..(rank and " You are #"..tostring(rank).." on this server." or "") )
|
||||
end
|
||||
local rank = Chess_GetRank(self, "Draughts")
|
||||
self:ChatPrint( "Your draughts Elo rating changed by "..tostring(mod).." to "..tostring(NewElo).."!" ..(rank and " You are #"..tostring(rank).." on this server." or "") )
|
||||
|
||||
Chess_UpdateElo( self )
|
||||
end
|
||||
function PLAYER:DraughtsWin( against ) self:DoDraughtsElo(1, against) end
|
||||
function PLAYER:DraughtsDraw( against ) self:DoDraughtsElo(0.5, against) end
|
||||
212
lua/chess/sv_sql.lua
Normal file
212
lua/chess/sv_sql.lua
Normal file
@@ -0,0 +1,212 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local nextTopUpdate = {}
|
||||
local playerResults = {}
|
||||
|
||||
local function InitChessLeaderboard()
|
||||
sql.Begin()
|
||||
local query = sql.Query( [[CREATE TABLE ChessLeaderboard (SteamID varchar(255), Username varchar(255), Elo int, DraughtsElo int);]] )
|
||||
sql.Commit()
|
||||
|
||||
if query==false then else print("Chess: Created Elo table") end
|
||||
end
|
||||
InitChessLeaderboard()
|
||||
|
||||
function Chess_UpdateElo( ply )
|
||||
if not IsValid(ply) then return end
|
||||
|
||||
local SelStr = [[SELECT * FROM ChessLeaderboard WHERE SteamID==]].. sql.SQLStr(ply:SteamID()) ..[[;]]
|
||||
sql.Begin()
|
||||
local Select = sql.Query( SelStr )
|
||||
sql.Commit()
|
||||
|
||||
local UpdateStr
|
||||
if Select==false then
|
||||
Error( "Chess: Save failed for player "..ply:Nick().." - Query error. "..sql.LastError().."\n" )
|
||||
elseif Select==nil then
|
||||
UpdateStr = [[INSERT INTO ChessLeaderboard (SteamID, Username, Elo, DraughtsElo) VALUES (]]..sql.SQLStr(ply:SteamID())..[[,]]..sql.SQLStr(ply:Nick())..[[,]]..sql.SQLStr(ply:GetChessElo())..[[,]]..sql.SQLStr(ply:GetDraughtsElo())..[[);]]
|
||||
else
|
||||
UpdateStr = [[UPDATE ChessLeaderboard SET Username=]]..sql.SQLStr(ply:GetName())..[[,Elo=]]..sql.SQLStr(ply:GetChessElo())..[[,DraughtsElo=]]..sql.SQLStr(ply:GetDraughtsElo())..[[ WHERE SteamID==]]..sql.SQLStr(ply:SteamID())..[[;]]
|
||||
end
|
||||
|
||||
sql.Begin()
|
||||
local Update = sql.Query( UpdateStr )
|
||||
sql.Commit()
|
||||
|
||||
if Update==false then
|
||||
Error( "Chess: Update failed for player "..ply:Nick().." - Query error. "..sql.LastError().."\n" )
|
||||
end
|
||||
|
||||
nextTopUpdate = {}
|
||||
playerResults = {}
|
||||
end
|
||||
function Chess_SetElo( steamID, newElo, isDraughts )
|
||||
if not tonumber(newElo) then return false,"Elo must be a number." end
|
||||
if type(steamID)=="Player" then
|
||||
if not IsValid(steamID) then return end
|
||||
steamID = steamID:SteamID()
|
||||
end
|
||||
|
||||
local ply = player.GetBySteamID(steamID)
|
||||
|
||||
local SelStr = [[SELECT * FROM ChessLeaderboard WHERE SteamID==]].. sql.SQLStr(steamID) ..[[;]]
|
||||
sql.Begin()
|
||||
local Select = sql.Query( SelStr )
|
||||
sql.Commit()
|
||||
|
||||
local UpdateStr
|
||||
if Select==nil then
|
||||
UpdateStr = [[INSERT INTO ChessLeaderboard (SteamID, Username, Elo, DraughtsElo) VALUES (]]..sql.SQLStr(steamID)..[[,]]..sql.SQLStr(IsValid(ply) and ply:Nick() or "N/A")..[[,]]..sql.SQLStr(IsValid(ply) and ply:GetChessElo() or 1400)..[[,]]..sql.SQLStr(IsValid(ply) and ply:GetDraughtsElo() or 1400)..[[);]]
|
||||
end
|
||||
|
||||
if isDraughts then
|
||||
UpdateStr = [[UPDATE ChessLeaderboard SET DraughtsElo=]]..sql.SQLStr(tonumber(newElo))..[[ WHERE SteamID==]]..sql.SQLStr(steamID)..[[;]]
|
||||
else
|
||||
UpdateStr = [[UPDATE ChessLeaderboard SET Elo=]]..sql.SQLStr(tonumber(newElo))..[[ WHERE SteamID==]]..sql.SQLStr(steamID)..[[;]]
|
||||
end
|
||||
|
||||
sql.Begin()
|
||||
local Update = sql.Query( UpdateStr )
|
||||
sql.Commit()
|
||||
|
||||
if Update==false then
|
||||
Error( "Chess: Update failed for player "..steamID.." - Query error. "..sql.LastError().."\n" )
|
||||
return false
|
||||
end
|
||||
|
||||
nextTopUpdate = {}
|
||||
playerResults = {}
|
||||
end
|
||||
function Chess_GetElo( steamID, isDraughts )
|
||||
if type(steamID)=="Player" then
|
||||
if not IsValid(steamID) then return end
|
||||
steamID = steamID:SteamID()
|
||||
end
|
||||
|
||||
local SelStr = [[SELECT * FROM ChessLeaderboard WHERE SteamID==]].. sql.SQLStr(steamID) ..[[;]]
|
||||
sql.Begin()
|
||||
local Select = sql.Query( SelStr )
|
||||
sql.Commit()
|
||||
|
||||
if Select==nil then
|
||||
return false, "Player does not have an Elo rating"
|
||||
end
|
||||
|
||||
if isDraughts then
|
||||
return Select[1].DraughtsElo or 1400
|
||||
else
|
||||
return Select[1].Elo or 1400 -- Chess
|
||||
end
|
||||
end
|
||||
|
||||
function Chess_GetRank( ply, typ )
|
||||
local query = string.gsub([[SELECT (
|
||||
SELECT COUNT(*)+1
|
||||
FROM ChessLeaderboard ordered
|
||||
WHERE (ordered.{ELO}) > (uo.{ELO})
|
||||
) AS Rank, (SELECT COUNT(*) FROM ChessLeaderboard) AS Count
|
||||
FROM ChessLeaderboard uo WHERE SteamID==]]..sql.SQLStr(ply:SteamID())..[[;]], "{ELO}", (typ=="Draughts" and [[DraughtsElo]] or [[Elo]]) )
|
||||
sql.Begin()
|
||||
local rank = sql.Query( query )
|
||||
sql.Commit()
|
||||
|
||||
if not (rank and rank[1] and rank[1].Rank and rank[1].Count) then return false end
|
||||
|
||||
return rank and rank[1] and rank[1].Rank, rank and rank[1] and rank[1].Count
|
||||
end
|
||||
|
||||
util.AddNetworkString( "Chess Top10" )
|
||||
local ValidType = {["Chess"] = true, ["Draughts"] = true}
|
||||
|
||||
local TopTable = {}
|
||||
net.Receive( "Chess Top10", function( len, ply )
|
||||
if not IsValid(ply) then return end
|
||||
|
||||
local typ = net.ReadString()
|
||||
if not (typ and ValidType[typ]) then typ = "Chess" end
|
||||
if not playerResults[typ] then playerResults[typ] = {} end
|
||||
|
||||
if playerResults[typ][ply] and (CurTime()<(playerResults[typ][ply].nextUpdate or 0)) then
|
||||
net.Start( "Chess Top10" )
|
||||
net.WriteString( typ )
|
||||
net.Send( ply )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if CurTime()>(nextTopUpdate[typ] or 0) then
|
||||
local query = string.gsub([[SELECT Username, SteamID, {ELO} as Elo, (
|
||||
SELECT COUNT(*)+1
|
||||
FROM ChessLeaderboard ordered
|
||||
WHERE (ordered.{ELO}) > (uo.{ELO})
|
||||
) AS Rank
|
||||
FROM ChessLeaderboard uo ORDER BY {ELO} DESC LIMIT 10;]], "{ELO}", (typ=="Draughts" and [[DraughtsElo]] or [[Elo]]) )
|
||||
sql.Begin()
|
||||
local Top10 = sql.Query( query )
|
||||
sql.Commit()
|
||||
|
||||
if Top10==false then
|
||||
Error( "Chess: Top10 retrieval failed - Query error. "..sql.LastError().."\n" )
|
||||
return
|
||||
elseif Top10==nil then
|
||||
Error( "Chess: Top10 retrieval failed - No data." )
|
||||
return
|
||||
end
|
||||
|
||||
TopTable = Top10
|
||||
|
||||
table.Empty(playerResults[typ])
|
||||
nextTopUpdate[typ] = CurTime() + 120
|
||||
end
|
||||
|
||||
local str = ""
|
||||
if (not playerResults[typ][ply]) or CurTime()<(playerResults[typ][ply].nextUpdate) then
|
||||
local rank,total = Chess_GetRank(ply, typ)
|
||||
playerResults[typ][ply] = {rank = rank, total = total}
|
||||
end
|
||||
local res = playerResults[typ][ply]
|
||||
str = (res.rank and res.total and res.rank.." of "..res.total) or res.rank or "N/A"
|
||||
|
||||
net.Start( "Chess Top10" )
|
||||
net.WriteString( typ )
|
||||
net.WriteTable( TopTable )
|
||||
|
||||
net.WriteString( str )
|
||||
net.WriteString(math.floor(nextTopUpdate[typ] - 120))
|
||||
net.Send( ply )
|
||||
|
||||
playerResults[typ][ply].nextUpdate = CurTime() + 30
|
||||
end)
|
||||
|
||||
-- function TestElo()
|
||||
-- local typ = ""
|
||||
|
||||
-- local query = string.gsub([[SELECT *,(
|
||||
-- SELECT COUNT(*)+1
|
||||
-- FROM ChessLeaderboard ordered
|
||||
-- WHERE (ordered.{ELO}) > (uo.{ELO})
|
||||
-- ) AS Rank, (SELECT COUNT(*) FROM ChessLeaderboard) AS Count
|
||||
-- FROM ChessLeaderboard uo ORDER BY {ELO} DESC;]], "{ELO}", (typ=="Draughts" and [[DraughtsElo]] or [[Elo]]) )
|
||||
-- sql.Begin()
|
||||
-- local Top10 = sql.Query( query )
|
||||
-- sql.Commit()
|
||||
|
||||
-- if Top10 then
|
||||
-- print( Top10 )
|
||||
-- PrintTable( Top10 )
|
||||
|
||||
-- print( Top10[1].Rank, type(Top10[1].Rank) )
|
||||
-- else
|
||||
-- print( sql.LastError() )
|
||||
-- end
|
||||
-- end
|
||||
|
||||
Reference in New Issue
Block a user