A simple credit plugin

Post Python examples to help other users.
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

A simple credit plugin

Postby 8guawong » Thu Nov 27, 2014 6:04 am

Syntax: Select all

import os.path
import pickle
from path import Path
from players.entity import PlayerEntity
from players.helpers import index_from_userid
from events import Event
from listeners.tick import TickRepeat


players_credit = {}
credit_repeat = {}

def load():
global players_credit
base_path = Path(__file__).parent
str_path = base_path + '/player_credit.db'
with open(str_path, 'rb') as player_credit:
players_credit = pickle.load(player_credit)

def unload():
save_database()
for userid in credit_repeat:
credit_repeat[userid].stop()
@Event
def player_connect(game_event):
userid = game_event.get_int('userid')
steamid = game_event.get_string('networkid')
if not steamid in players_credit:
players_credit[steamid] = {}
players_credit[steamid]['credit'] = 0
credit_repeat[userid] = TickRepeat(giveCredits, steamid)
credit_repeat[userid].start(60, 0)

@Event
def player_disconnect(game_event):
userid = game_event.get_int('userid')
credit_repeat[userid].stop()
save_database()

def save_database():
base_path = Path(__file__).parent
str_path = base_path + '/player_credit.db'
with open(str_path, 'wb') as player_credit:
pickle.dump(players_credit, player_credit)

def giveCredits(steamid):
players_credit[steamid]['credit'] += 1
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Sun Nov 30, 2014 5:36 pm

Very nice :)

A couple pointers, though. First, if you are going to use path.Path, you might as well fully utilize it instead of also using os.path natively. Also, you should look into Python's context management and the 'with' statement:

Syntax: Select all

str_path = Path(__file__).parent.joinpath('player_credit.db')

def load():
global players_credit
if not str_path.isfile():
return
with str_path.open('rb') as open_file:
players_credit = pickle.load(open_file)


def save_database():
with str_path.open('wb') as open_file:
pickle.dump(players_credit, open_file)



Also, you pass giveCredits the player's SteamID, but then get the SteamID again using the userid. Instead, just pass the SteamID and not the userid and use that to add credits. And, your 'unload' function will error, as you have not defined store_repeat.


I would probably rather create a class that stores players by their userid in a dictionary:

Syntax: Select all

from listeners.tick import TickRepeat
from listeners.tick import TickRepeatStatus
from players.entity import PlayerEntity
from players.helpers import index_from_userid


class PlayerDictionary(dict):
def __missing__(self, userid):
value = self[userid] = PlayerInstance(userid)
return value

def __delitem__(self, userid):
if userid not in self:
return
self[userid].stop_repeat()
super(PlayerDictionary, self).__delitem__(userid)

def clear(self):
for item in list(self):
del self[item]

player_dictionary = PlayerDictionary()


class PlayerInstance(PlayerEntity):
def __new__(cls, userid):
index = index_from_userid(userid)
self = super(PlayerInstance, cls).__new__(cls, index)
return self

def __init__(self, userid):
self._repeat = TickRepeat(self.give_credits)

@property
def repeat(self):
return self._repeat

def start_repeat(self):
if self.repeat.status is TickRepeatStatus.STOPPED:
self.repeat.start(60, 0)

def stop_repeat(self):
if self.repeat.status is TickRepeatStatus.RUNNING:
self.repeat.stop()

def give_credits(self):
players_credit[self.steamid]['credit'] += 1


def unload():
player_dictionary.clear()


@Event
def player_activate(game_event):
player_dictionary[game_event.get_int('userid')].start_repeat()


@Event
def player_disconnect(game_event):
del player_dictionary[game_event.get_int('userid')]
save_database()
Image
8guawong
Senior Member
Posts: 148
Joined: Sat Sep 20, 2014 3:06 am

Postby 8guawong » Mon Dec 01, 2014 12:29 am

thanks for the comment
fixed the store_repeat and passing userid getting steamid useless crap
i copied the code from store plugin i was doing

not very good with programming so don't know about other stuff you said i.e. class.. context.. etc. :o
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Mon Dec 01, 2014 1:05 am

8guawong wrote:not very good with programming so don't know about other stuff you said i.e. class.. context.. etc. :o

I mention those things to help you, and others, learn. I cannot state this enough, but a big part of the idiology of this plugin is to help people learn how to properly program. And, that definitely includes learning object oriented programming (OOP).

If you have questions, please feel free to ask.
Image
Mishimeow
Junior Member
Posts: 1
Joined: Mon Jan 25, 2016 1:35 am

Postby Mishimeow » Mon Jan 25, 2016 1:39 am

Hi guys, Just found SP today via the new WCGO release.
For years I've been maintaining servers with little help from knowledgeable programmers.
I have a great respect for the intention of SP and the programmers who take time out of their day to help others grow.
I commend you, Satoon. And all newbie programmers who aim to add to the community.
Your positive attitude will make this the perfect environment for a successful community.


I will be starting my programming study this year and at college.
This seems like the perfect place to work.

I look forward to making mods with you guys :cool:

Return to “Code examples / Cookbook”

Who is online

Users browsing this forum: No registered users and 23 guests