HL2DM-scoreboard and stats

A place for requesting new Source.Python plugins to be made for your server.

Please request only one plugin per thread.
User avatar
daren adler
Senior Member
Posts: 328
Joined: Sat May 18, 2019 7:42 pm

HL2DM-scoreboard and stats

Postby daren adler » Mon Oct 26, 2020 7:42 pm

Hello game scripters :smile: I was wondering if someone could make a scoreboard and stats like it looks in this picture? https://steamuserimages-a.akamaihd.net/ ... 0795F5F5C/ on the left. right and botom in this picture, the writing in green, the Session, the timeleft and global stats and time and date. :embarrassed: I know ive asked before here viewtopic.php?f=37&t=2400 but did not work. I was thinking maybe either hit tab button to see them and or see them after death also.
User avatar
PEACE
Member
Posts: 50
Joined: Mon Oct 12, 2020 1:13 pm

Re: HL2DM-scoreboard and stats

Postby PEACE » Tue Oct 27, 2020 12:27 am

Wow that would be awesome , great Idea for sure ....
User avatar
PEACE
Member
Posts: 50
Joined: Mon Oct 12, 2020 1:13 pm

Re: HL2DM-scoreboard and stats

Postby PEACE » Wed Dec 02, 2020 3:27 am

The left and Right Stats you showed when you hold the Tab key also would be nice if they were perm stored so you can see you progress when you return to the server . This seems like allot of work for someone to do but it sure doesn't hurt to ask :)


/PEACE
User avatar
PEACE
Member
Posts: 50
Joined: Mon Oct 12, 2020 1:13 pm

Re: HL2DM-scoreboard and stats

Postby PEACE » Wed Dec 16, 2020 11:25 pm

I take it no one wants to attempt this one so ill stop asking and to all our scriptors have a good safe Holiday :)


Peace ..........
User avatar
Kami
Global Moderator
Posts: 263
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: HL2DM-scoreboard and stats

Postby Kami » Sun Dec 20, 2020 9:35 pm

Hey guys, I tried my best to recreate the screenshot. Painkiller uses a bigger mod which adds things like "postal" and "sensei" which I did not include.

This plugin is focused on functionality and the code is quite messy/unorganized. If anyone is willing to clean it up he/she is welcome to do so.

This stats plugin contains:

- Session and global stats keeping track of: Points, Kills, Deaths, Suicides, Headshots, KDR, Killstreak
- SQL (SQL-Alchemy) database for permanent saving
- say/client command "rank" to show your current rank sorted by points (global kills - global deaths)
- Ingame overlay triggered by pressing Tab (scoreboard button) which displays session and global stats, currenty day and time and timeleft.

Syntax: Select all

from colors import GREEN
from commands.say import SayCommand
from commands.client import ClientCommand
from cvars import ConVar
from contextlib import contextmanager
from entities.entity import BaseEntity
from events import Event
from filters.players import PlayerIter
from listeners import ListenerManager
from listeners import ListenerManagerDecorator
from listeners import OnClientActive, OnPlayerRunCommand, OnLevelInit
from listeners.tick import Repeat, Delay

from messages import HudMsg
from messages.base import SayText2

from paths import PLUGIN_DATA_PATH, GAME_PATH
from players.constants import PlayerButtons, HitGroup, PlayerStates
from players.entity import Player
from players.helpers import index_from_userid, userid_from_index,userid_from_edict,index_from_steamid
from threading import Thread

from paths import PLUGIN_DATA_PATH, GAME_PATH
from queue import Empty, Queue
import time

#SQL Alchemy
from sqlalchemy import Column, ForeignKey, Integer, String, Index, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql.expression import insert
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine, desc


STATS_DATA_PATH = PLUGIN_DATA_PATH / 'stats'
if not STATS_DATA_PATH.exists():
STATS_DATA_PATH.makedirs()
CORE_DB_PATH = STATS_DATA_PATH / 'players.db'
CORE_DB_REL_PATH = CORE_DB_PATH.relpath(GAME_PATH.parent)

player_loaded = {}
output = Queue()
statsplayers = {}
player_session = {}
stats_screen = {}
stats_active = {}
stats_rank = {}

map_end_time = None
mp_timelimit = ConVar('mp_timelimit')

stats_button = PlayerButtons.SCORE

npc_list = ['npc_zombie',
'npc_manhack',
'npc_headcrab',
'npc_antilion',
'npc_antilionguard',
'npc_clawscanner',
'npc_combinedropship',
'npc_combinegunship',
'npc_crow',
'combine_mine',
'npc_headcrab_black',
'npc_headcrab_fast',
'npc_helicopter',
'npc_hunter',
'npc_ichthyosaur',
'npc_ministriper',
'npc_missildefense',
'npc_mortarsynth',
'npc_pigeon',
'npc_poisonzombie',
'npc_rollermine',
'npc_sniper',
'npc_stalker',
'npc_strider',
'npc_turret_ceiling',
'npc_turret_floor',
'npc_turret_ground',
'npc_vortigaunt',
'npc_zombie_torso',
'npc_zombine'
]

@contextmanager
def session_scope():
session = Session()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()

# =============================================================================
# >> DATABASE
# =============================================================================
Base = declarative_base()
engine = create_engine(f'sqlite:///{CORE_DB_REL_PATH}')

class Players(Base):
__tablename__ = 'Players'
UserID = Column(Integer,nullable=False,primary_key=True)
steamid = Column(String(30),nullable=False)
name = Column(String(30),nullable=False)
kills = Column(Integer,default=0)
deaths = Column(Integer,default=0)
headshots = Column(Integer,default=0)
suicides = Column(Integer,default=0)
killstreak = Column(Integer,default=0)
distance = Column(Float,default=0.0)
npc_kills = Column(Integer,default=0)
Index('playersIndex', steamid)

if not engine.dialect.has_table(engine, 'Players'):
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)


# =============================================================================
# >> LOAD
# =============================================================================
def load():
for player in PlayerIter():
statsplayers[player.userid] = StatsPlayer(player.userid)
init_player_session(player.userid)
Delay(0.1,init_timeleft)
_load_ranks()


def init_timeleft():
global map_end_time
timelimit = mp_timelimit.get_int() * 60
map_end_time = time.time() + timelimit if timelimit else None

def _load_ranks():
with session_scope() as session:
query = session.query(Players).all()
if query != None:
for (user) in query:
stats_rank[user.steamid] = {}
stats_rank[user.steamid]['name'] = user.name
stats_rank[user.steamid]['kills'] = user.kills
stats_rank[user.steamid]['deaths'] = user.deaths
stats_rank[user.steamid]['points'] = user.kills-user.deaths



# =============================================================================
# >> HELPERS
# =============================================================================
@Repeat
def repeat():
try:
callback = output.get_nowait()
except Empty:
pass
else:
callback()
repeat.start(0.1)

@Repeat
def show_stats_repeat():
for player in PlayerIter('all'):
if stats_screen[player.userid] == True:
session_message = "Session Stats:\n\n"+"Points: "+str(player_session[player.userid]["kills"]-player_session[player.userid]["deaths"])+"\nKills: "+str(player_session[player.userid]["kills"])+"\nDeaths: "+str(player_session[player.userid]["deaths"])+"\nSuicides: "+str(player_session[player.userid]["suicides"])+"\nHeadshots: "+str(player_session[player.userid]['headshots'])+"\nKDR: "+str(calc_session_kdr(player_session[player.userid]["kills"],player_session[player.userid]["deaths"]))+"\nKillstreak: "+str(player_session[player.userid]["highest_killstreak"])+"\nNPC Kills: "+str(player_session[player.userid]["npc_kills"])
HudMsg(
message=session_message,
x=0.01,
y=-0.60,
color1=GREEN,
color2=GREEN,
effect=0,
fade_in=0.05,
fade_out=0.1,
hold_time=0.5,
fx_time=1.0,
channel=0,
).send(player.index)

global_message = "Global Stats:\n\n"+"Points: "+str(statsplayers[player.userid].kills-statsplayers[player.userid].deaths)+"\nKills: "+str(statsplayers[player.userid].kills)+"\nDeaths: "+str(statsplayers[player.userid].deaths)+"\nSuicides: "+str(statsplayers[player.userid].suicides)+"\nHeadshots: "+str(statsplayers[player.userid].headshots)+"\nKDR: "+str(statsplayers[player.userid].calc_kdr(statsplayers[player.userid].kills,statsplayers[player.userid].deaths))+"\nKillstreak: "+str(statsplayers[player.userid].killstreak)+"\nNPC Kills: "+str(statsplayers[player.userid].npc_kills)
HudMsg(
message=global_message,
x=0.85,
y=-0.60,
color1=GREEN,
color2=GREEN,
effect=0,
fade_in=0.05,
fade_out=0.1,
hold_time=0.5,
fx_time=1.0,
channel=1,
).send(player.index)
time_message = time.strftime('%a, %m.%y. %H:%M:%S',time.localtime(time.time()))
HudMsg(
message=time_message,
x=-1,
y=0.07,
color1=GREEN,
color2=GREEN,
effect=0,
fade_in=0.05,
fade_out=0.1,
hold_time=0.5,
fx_time=1.0,
channel=2,
).send(player.index)
timeleft = map_end_time - time.time()
minutes, seconds = divmod(timeleft, 60)
timeleft_message = "Timeleft: %.0f minutes and %.0f seconds remaining." % (minutes,seconds)
HudMsg(
message=timeleft_message,
x=-1,
y=0.90,
color1=GREEN,
color2=GREEN,
effect=0,
fade_in=0.05,
fade_out=0.1,
hold_time=0.5,
fx_time=1.0,
channel=3,
).send(player.index)
elif stats_active[player.userid] == True:
for i in range(4):
HudMsg(
message="",
x=0.01,
y=-0.88,
color1=GREEN,
color2=GREEN,
effect=0,
fade_in=0.05,
fade_out=0.5,
hold_time=0.5,
fx_time=1.0,
channel=i,
).send(player.index)
stats_active[player.userid] = False


show_stats_repeat.start(0.1)


def exists(userid):
try:
index_from_userid(userid)
except ValueError:
return False
return True

def init_player_session(userid):
if userid not in player_session:
player_session[userid] = {}
player_session[userid]["kills"] = 0
player_session[userid]["deaths"] = 0
player_session[userid]["suicides"] = 0
player_session[userid]["killstreak"] = 0
player_session[userid]["highest_killstreak"] = 0
player_session[userid]["headshots"] = 0
player_session[userid]["npc_kills"] = 0

def calc_session_kdr(kills,deaths):
if kills == 0: kills = 1
if deaths == 0: deaths = 1
return ("%.2f" % (kills/deaths))

# =============================================================================
# >> PLAYER CLASS
# =============================================================================
class StatsPlayer(object):
def __init__(self,userid):
self.userid = int(userid)
self.player_entity = Player.from_userid(self.userid)
self.index = self.player_entity.index
self.steamid = self.player_entity.uniqueid
self.name = self.remove_warnings(self.player_entity.name)

#Dict to check for load status
player_loaded[self.userid] = False

stats_screen[self.userid] = False
stats_active[self.userid] = False


#Player data
self.UserID = -1
self.points = 0
self.kills = 0
self.deaths = 0
self.headshots = 0
self.suicides = 0
self.kdr = 0.0
self.killstreak = 0
self.distance = 0.0
self.npc_kills = 0

Thread(target=self._load_from_database).start()

def _load_from_database(self):
with session_scope() as session:
#Player data

player = session.query(Players).filter(Players.steamid==self.steamid).one_or_none()
if player is None:
player = Players(steamid=self.steamid,name=self.name)
session.add(player)
session.commit()
self.UserID = player.UserID
self.kills = player.kills
self.deaths = player.deaths
self.headshots = player.headshots
self.suicides = player.suicides
self.killstreak = player.killstreak
self.distance = player.distance
self.points = self.kills-self.deaths
self.kdr = self.calc_kdr(self.kills,self.deaths)
self.npc_kills = player.npc_kills
_load_ranks()

output.put(self._on_finish)

def _on_finish(self):
if exists(self.userid):
OnPlayerLoaded.manager.notify(self)

def save(self):
if exists(self.userid):
Thread(target=self._save_player_to_database).start()

def _save_player_to_database(self):
with session_scope() as session:
player = session.query(Players).filter(Players.UserID==self.UserID).one_or_none()
player.steamid = self.steamid
player.name = self.name
player.kills = self.kills
player.deaths = self.deaths
player.headshots = self.headshots
player.suicides = self.suicides
player.killstreak = self.killstreak
player.distance = self.distance
player.npc_kills = self.npc_kills

session.commit()

output.put(self._on_player_saved)

def _on_player_saved(self):
if exists(self.userid):
OnPlayerSaved.manager.notify(self)

def remove_warnings(self, value):
return str(value).replace("'", "").replace('"', '')

def calc_kdr(self,kills,deaths):
if kills == 0: kills = 1
if deaths == 0: deaths = 1
return ("%.2f" % (kills/deaths))


for player in PlayerIter('all'):
statsplayers[player.userid] = StatsPlayer(player.userid)
init_player_session(player.userid)

# =============================================================================
# >> LISTENERS
# =============================================================================
class OnPlayerSaved(ListenerManagerDecorator):
manager = ListenerManager()

class OnPlayerLoaded(ListenerManagerDecorator):
manager = ListenerManager()

@OnPlayerLoaded
def on_loaded(statsplayer):
player_loaded[statsplayer.userid] = True

@OnPlayerRunCommand
def _on_player_run_command(player, usercmd):
if player.is_bot():
return
if usercmd.buttons & stats_button:
stats_screen[player.userid] = True
stats_active[player.userid] = True
else:
stats_screen[player.userid] = False

@OnLevelInit
def level_init(map_name=None):
global map_end_time
timelimit = mp_timelimit.get_int() * 60
map_end_time = time.time() + timelimit if timelimit else None
for player in PlayerIter('all'):
statsplayers[player.userid].save()

@OnClientActive
def on_client_active(index):
statsplayers[Player(index).userid] = StatsPlayer(Player(index).userid)
init_player_session(userid_from_index(index))

# =============================================================================
# >> EVENTS
# =============================================================================
@Event('player_disconnect')
def player_disconnect(ev):
userid = ev.get_int('userid')
player_entity = Player(index_from_userid(userid))

statsplayers[ev['userid']].save()
if userid in statsplayers:
statsplayers[ev['userid']].name = statsplayers[ev['userid']].remove_warnings(player_entity.name)
statsplayers[ev['userid']].save()

@Event('player_hurt')
def player_hurt(ev):
if ev['attacker'] != 0:
attacker = Player.from_userid(ev['attacker'])
victim = Player.from_userid(ev['userid'])
if victim.hitgroup == HitGroup.HEAD:
player_session[attacker.userid]["headshots"] += 1
statsplayers[attacker.userid].headshots += 1


@Event('player_death')
def player_death(ev):
victim_userid = ev['userid']
attacker_userid = ev['attacker']
victim = Player.from_userid(ev['userid'])
if ev['attacker'] != 0:
attacker = Player.from_userid(ev['attacker'])
if victim.userid != attacker.userid:
statsplayers[attacker.userid].kills += 1
player_session[attacker.userid]["kills"] += 1

player_session[attacker.userid]["killstreak"] += 1
if player_session[attacker.userid]["killstreak"] > statsplayers[attacker.userid].killstreak:
statsplayers[attacker.userid].killstreak = player_session[attacker.userid]["killstreak"]
if player_session[attacker.userid]["killstreak"] > player_session[attacker.userid]["highest_killstreak"]:
player_session[attacker.userid]["highest_killstreak"] = player_session[attacker.userid]["killstreak"]

statsplayers[victim.userid].deaths += 1
player_session[victim.userid]["deaths"] += 1

if player_session[victim.userid]["killstreak"] > player_session[victim.userid]["highest_killstreak"]:
player_session[victim.userid]["highest_killstreak"] = player_session[victim.userid]["killstreak"]
player_session[victim.userid]["killstreak"] = 0

stats_rank[attacker.uniqueid]['points'] = statsplayers[attacker.userid].kills-statsplayers[attacker.userid].deaths
stats_rank[victim.uniqueid]['points'] = statsplayers[victim.userid].kills-statsplayers[victim.userid].deaths
else:
statsplayers[victim.userid].suicides += 1
player_session[victim.userid]["suicides"] += 1

statsplayers[victim.userid].deaths += 1
player_session[victim.userid]["deaths"] += 1

player_session[victim.userid]["killstreak"] = 0

stats_rank[victim.uniqueid]['points'] = statsplayers[victim.userid].kills-statsplayers[victim.userid].deaths

@Event('entity_killed')
def npc_killed(event):
classname = BaseEntity(event['entindex_killed']).classname
if classname in npc_list:
player = Player(event['entindex_attacker'])
player_session[player.userid]["npc_kills"] += 1
statsplayers[player.userid].npc_kills += 1


# =============================================================================
# >> CLIENTCOMMANDS
# =============================================================================
@ClientCommand('rank')
@SayCommand('rank')
def rank_command(command, index, team_only=False):
player = Player(index)
rank_list = stats_rank.values()
rank_list = sorted(stats_rank, key=lambda x: stats_rank[x]['points'],reverse=True)
i = 0
for x in rank_list:
i+=1
if player.uniqueid == x:
rank = i
break
SayText2("\x04[Stats]\x03 Your rank is \x04%s \x03of \x04%s \x03with \x04%s \x03points." % (i, len(rank_list),stats_rank[player.uniqueid]['points'])).send(index)


Image

Image
User avatar
daren adler
Senior Member
Posts: 328
Joined: Sat May 18, 2019 7:42 pm

Re: HL2DM-scoreboard and stats

Postby daren adler » Sun Dec 20, 2020 10:40 pm

Thank you very much Kami :wink: . I tested it and works, but i got this in my log.

Code: Select all

2020-12-20 16:19:51 - sp   -   EXCEPTION   
[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\source-python\events\listener.py", line 92, in fire_game_event
    callback(game_event)
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 383, in player_hurt
    attacker = Player.from_userid(ev['attacker'])
  File "..\addons\source-python\packages\source-python\players\_base.py", line 109, in from_userid
    return cls(index_from_userid(userid), caching=caching)

ValueError: Conversion from "Userid" (0) to "Index" failed.


2020-12-20 16:19:54 - sp   -   EXCEPTION   
[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\source-python\events\listener.py", line 92, in fire_game_event
    callback(game_event)
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 410, in player_death
    stats_rank[attacker.steamid]['points'] = statsplayers[attacker.userid].kills-statsplayers[attacker.userid].deaths

KeyError: 'BOT'


2020-12-20 16:19:57 - sp   -   EXCEPTION   
[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\source-python\events\listener.py", line 92, in fire_game_event
    callback(game_event)
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 410, in player_death
    stats_rank[attacker.steamid]['points'] = statsplayers[attacker.userid].kills-statsplayers[attacker.userid].deaths

KeyError: '[U:1:37220659]'
User avatar
Kami
Global Moderator
Posts: 263
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: HL2DM-scoreboard and stats

Postby Kami » Sun Dec 20, 2020 10:47 pm

That happens when you damage yourself I think. I updated the plugin to fix that error.
User avatar
PEACE
Member
Posts: 50
Joined: Mon Oct 12, 2020 1:13 pm

Re: HL2DM-scoreboard and stats

Postby PEACE » Sun Dec 20, 2020 11:11 pm

Kami,
Your the best brother was awesome of you to release this for us !! I use to have one made by RLS years ago it had a few more things in it like NPC kills , barrels blown , Health kits and it made it own database but some of the things stopped working or didnt update , this will be a good replacement ..

Me and daren also run Postal so you could have left that in :)

we thank you

/Peace
User avatar
daren adler
Senior Member
Posts: 328
Joined: Sat May 18, 2019 7:42 pm

Re: HL2DM-scoreboard and stats

Postby daren adler » Sun Dec 20, 2020 11:34 pm

Only one now.

Code: Select all

2020-12-20 17:31:56 - sp   -   EXCEPTION   
[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\source-python\events\listener.py", line 92, in fire_game_event
    callback(game_event)
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 411, in player_death
    stats_rank[attacker.steamid]['points'] = statsplayers[attacker.userid].kills-statsplayers[attacker.userid].deaths

KeyError: 'BOT'
User avatar
Kami
Global Moderator
Posts: 263
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: HL2DM-scoreboard and stats

Postby Kami » Mon Dec 21, 2020 12:25 am

Updated the plugin to fix the error.
User avatar
PEACE
Member
Posts: 50
Joined: Mon Oct 12, 2020 1:13 pm

Re: HL2DM-scoreboard and stats

Postby PEACE » Mon Dec 21, 2020 1:05 am

Kami,

Good to see you I remember you bank when you helped me fix some issues in WCS .
Is it allot of trouble to add "Killed NPC's" or that Postal part , just askenI know im asking allot of your time ...
Thanks for you good work

/Peace
User avatar
daren adler
Senior Member
Posts: 328
Joined: Sat May 18, 2019 7:42 pm

Re: HL2DM-scoreboard and stats

Postby daren adler » Mon Dec 21, 2020 1:05 am

I went and added the new one and still get these.

Code: Select all

2020-12-20 21:21:50 - sp   -   EXCEPTION   
[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\source-python\events\listener.py", line 92, in fire_game_event
    callback(game_event)
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 399, in player_death
    attacker = Player.from_userid(ev['attacker'])
  File "..\addons\source-python\packages\source-python\players\_base.py", line 109, in from_userid
    return cls(index_from_userid(userid), caching=caching)

ValueError: Conversion from "Userid" (0) to "Index" failed.


2020-12-20 21:22:53 - sp   -   EXCEPTION   
[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\source-python\events\listener.py", line 92, in fire_game_event
    callback(game_event)
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 428, in player_death
    stats_rank[victim.steamid]['points'] = statsplayers[victim.userid].kills-statsplayers[victim.userid].deaths

KeyError: 'BOT'
User avatar
Kami
Global Moderator
Posts: 263
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: HL2DM-scoreboard and stats

Postby Kami » Mon Dec 21, 2020 10:10 am

Error should be fixed now.

PEACE wrote:Kami,

Good to see you I remember you bank when you helped me fix some issues in WCS .
Is it allot of trouble to add "Killed NPC's" or that Postal part , just askenI know im asking allot of your time ...
Thanks for you good work

/Peace


The problem with this is, that this would require me to have access to the postal plugin and the npc plugin you are using. Also it would make this plugin require those plugins.
User avatar
PEACE
Member
Posts: 50
Joined: Mon Oct 12, 2020 1:13 pm

Re: HL2DM-scoreboard and stats

Postby PEACE » Mon Dec 21, 2020 1:52 pm

Kami ,

Its the same postal Painkiller uses , 12 kills , all you have to do is make is resister the amount of kills in a row for Postal and Sensi , but its ok my friend , you could just give me the one you made for it and i can see if it works . and the NPC's is the Silent Hill made here , it just has to register the kills from that mod ...



/Peace
Last edited by PEACE on Mon Dec 21, 2020 3:17 pm, edited 1 time in total.
User avatar
daren adler
Senior Member
Posts: 328
Joined: Sat May 18, 2019 7:42 pm

Re: HL2DM-scoreboard and stats

Postby daren adler » Mon Dec 21, 2020 3:03 pm

I updated it and still get this.

Code: Select all

2020-12-21 09:00:54 - sp   -   EXCEPTION   
[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\source-python\events\listener.py", line 92, in fire_game_event
    callback(game_event)
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 413, in player_death
    stats_rank[victim.steamid]['points'] = statsplayers[victim.userid].kills-statsplayers[victim.userid].deaths

KeyError: 'BOT'
User avatar
Kami
Global Moderator
Posts: 263
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: HL2DM-scoreboard and stats

Postby Kami » Mon Dec 21, 2020 3:27 pm

Added NPC Kills to the stats.

I also tried to fix the KeyError, let me know if it works.
User avatar
daren adler
Senior Member
Posts: 328
Joined: Sat May 18, 2019 7:42 pm

Re: HL2DM-scoreboard and stats

Postby daren adler » Mon Dec 21, 2020 3:50 pm

Kami wrote:Added NPC Kills to the stats.

I also tried to fix the KeyError, let me know if it works.


Ok i will check, thank you for what you are doing :cool: :cool: :cool:

Now i get this

Code: Select all

2020-12-21 09:52:18 - sp   -   MESSAGE   [SP] Loading plugin 'scoreboard'...
2020-12-21 09:52:18 - sp   -   EXCEPTION   
[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\site-packages\sqlalchemy\engine\base.py", line 1139, in _execute_context
    context)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\engine\default.py", line 450, in do_execute
    cursor.execute(statement, parameters)
sqlite3.OperationalError: no such column: Players.npc_kills

The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\source-python\plugins\command.py", line 164, in load_plugin
    plugin = self.manager.load(plugin_name)
  File "..\addons\source-python\packages\source-python\plugins\manager.py", line 207, in load
    plugin._load()
  File "..\addons\source-python\packages\source-python\plugins\instance.py", line 76, in _load
    self.module.load()
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 132, in load
    _load_ranks()
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 142, in _load_ranks
    query = session.query(Players).all()
  File "..\addons\source-python\packages\site-packages\sqlalchemy\orm\query.py", line 2613, in all
    return list(self)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\orm\query.py", line 2761, in __iter__
    return self._execute_and_instances(context)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\orm\query.py", line 2776, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\engine\base.py", line 914, in execute
    return meth(self, multiparams, params)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\sql\elements.py", line 323, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\engine\base.py", line 1010, in _execute_clauseelement
    compiled_sql, distilled_params
  File "..\addons\source-python\packages\site-packages\sqlalchemy\engine\base.py", line 1146, in _execute_context
    context)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\engine\base.py", line 1341, in _handle_dbapi_exception
    exc_info
  File "..\addons\source-python\packages\site-packages\sqlalchemy\util\compat.py", line 202, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\util\compat.py", line 185, in reraise
    raise value.with_traceback(tb)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\engine\base.py", line 1139, in _execute_context
    context)
  File "..\addons\source-python\packages\site-packages\sqlalchemy\engine\default.py", line 450, in do_execute
    cursor.execute(statement, parameters)

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: Players.npc_kills [SQL: 'SELECT "Players"."UserID" AS "Players_UserID", "Players".steamid AS "Players_steamid", "Players".name AS "Players_name", "Players".kills AS "Players_kills", "Players".deaths AS "Players_deaths", "Players".headshots AS "Players_headshots", "Players".suicides AS "Players_suicides", "Players".killstreak AS "Players_killstreak", "Players".distance AS "Players_distance", "Players".npc_kills AS "Players_npc_kills" \nFROM "Players"']
User avatar
PEACE
Member
Posts: 50
Joined: Mon Oct 12, 2020 1:13 pm

Re: HL2DM-scoreboard and stats

Postby PEACE » Mon Dec 21, 2020 3:56 pm

Kami,

Im getting no hud display at all when i hold the Tab Key , nothing
User avatar
Kami
Global Moderator
Posts: 263
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: HL2DM-scoreboard and stats

Postby Kami » Mon Dec 21, 2020 4:04 pm

Oh sorry, I forgot to mention, you need to remove the old database, as I added a new table (npc_kills) to it.

You can find it under "addons/sourcepython/data/plugins/scoreboard/players.db"
User avatar
daren adler
Senior Member
Posts: 328
Joined: Sat May 18, 2019 7:42 pm

Re: HL2DM-scoreboard and stats

Postby daren adler » Mon Dec 21, 2020 4:10 pm

ok got it, ty :cool: :cool: (Update) i still get this

Code: Select all

2020-12-21 10:30:25 - sp   -   EXCEPTION   
[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\packages\source-python\events\listener.py", line 92, in fire_game_event
    callback(game_event)
  File "..\addons\source-python\plugins\scoreboard\scoreboard.py", line 453, in player_death
    stats_rank[attacker.steamid]['points'] = statsplayers[attacker.userid].kills-statsplayers[attacker.userid].deaths

KeyError: 'BOT'
Last edited by daren adler on Mon Dec 21, 2020 4:38 pm, edited 2 times in total.

Return to “Plugin Requests”

Who is online

Users browsing this forum: No registered users and 15 guests