Few questions regarding S.P and SourceMod

All other Source.Python topics and issues.
nergal
Member
Posts: 57
Joined: Sun Mar 15, 2015 2:58 pm

Few questions regarding S.P and SourceMod

Postby nergal » Mon Jun 01, 2015 8:39 am

I've found out recently that there is TF2 support for S.p which begs me to ask....

1. Will S.P and SourceMod work without conflicting each other? My admins don't want to switch to S.P yet because they're still used to SM. Will having both S.P and SM cause crashes or other issues?

2. SM provided cookies and mysql for storage; does S.P have such storage?

3. Considering SM's SourcePawn API that I'm very familiar with, does Source.Python have the same kind of API or additional?

For example, how would would I turn this into a .py plugin?


Syntax: Select all

int iProPlayer[ MXPLYR ];

public void OnPluginStart()
{
RegConsoleCmd("sm_pro", CommandSetWepAlpha, "Weapon Alpha");
RegConsoleCmd("sm_angles", CommandInfo, "Weapon Angles");
RegAdminCmd("sm_adpro", CommandSetAdminWepAlpha, ADMFLAG_SLAY, "Admin Weapon Alpha");

HookEvent("player_spawn", Eventery);
HookEvent("post_inventory_application", Eventery);

for (int i = 1; i <= MaxClients; i++)
{
if ( !IsValidClient(i) ) continue;
OnClientPutInServer(i);
}
}
public void OnClientPutInServer( int client )
{
iProPlayer[client] = -1;
}

public Action Eventery(Event event, const char[] name, bool dontBroadcast)
{
int i = GetClientOfUserId( event.GetInt("userid") );
if ( IsValidClient(i) )
{
if ( iProPlayer[i] != -1 ) SetWeaponInvis( i, iProPlayer[i] );
}
return Plugin_Continue;
}
stock void SetWeaponInvis(int client, int &alpha)
{
for (int i = 0; i < 5; i++)
{
int entity = GetPlayerWeaponSlot(client, i);
if ( IsValidEdict(entity) && IsValidEntity(entity) )
{
if (alpha < 0) alpha = 0;
else if (alpha > 255) alpha = 255;
SetEntityRenderMode(entity, RENDER_TRANSCOLOR);
SetEntityRenderColor(entity, 150, 150, 150, alpha);
}
}
return;
}
stock bool IsValidClient(int client, bool replaycheck = true)
{
if ( client <= 0 || client > MaxClients) return false;
if ( !IsClientInGame(client) ) return false;
if ( GetEntProp(client, Prop_Send, "m_bIsCoaching") ) return false;
if ( replaycheck ) if ( IsClientSourceTV(client) || IsClientReplay(client) ) return false;
return true;
}
stonedegg
Senior Member
Posts: 141
Joined: Sun Aug 12, 2012 11:45 am

Postby stonedegg » Mon Jun 01, 2015 11:55 am

1. Yes, I haven't experienced any crashes.

2. Yes, for mysql you can use PyMySQL. (Maybe this should be integrated into the site-packages folder?) For cookies, Python provides besides sqlite3 pickle, which is very easy to use.

3. Well, SourcePython provides Python ;) Every script you can write in Python can be executed on your server as a SourcePython plugin. To learn more about SourcePython itself, read the wiki (not yet complete tho) or ask in the forums.


Your sourcemod script is not complete (command callbacks missing, the keyvalue for the iProPlayer is never being set to anything else than -1), but this is how it would look:


Syntax: Select all

# SourcePython imports
from players.entity import PlayerEntity
from players.helpers import index_from_userid

from weapons.entity import WeaponEntity

from entities.constants import RenderMode

from events import Event
from colors import Color

# create a dictionary
iProPlayer = {}


@Event
def player_connect(game_event):
userid = game_event.get_int('userid')

# add the player to the dictionary
iProPlayer[userid] = -1

@Event
def player_spawn(game_event):
eventery(game_event.get_int('userid')

@Event
def post_inventory_application(game_event):
eventery(game_event.get_int('userid')

def eventery(userid):
if iProPlayer[userid] != -1:
set_weapon_invis(userid, iProPlayer[userid])

def set_weapon_invis(userid, alpha):
index = index_from_userid(userid)
player = PlayerEntity(userid)

if alpha < 0:
alpha = 0
elif alpha > 255:
alpha = 255

for weapon_index in player.weapon_indexes():
entity = WeaponEntity(weapon_index)
entity.render_mode = RenderMode.TRANS_COLOR
entity.set_color(Color(150, 150, 150, alpha))
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Mon Jun 01, 2015 12:44 pm

As far as mysql support, we only provide site-packages within SP that we are using within the API. In the future, we do plan on allowing plugins to have a requirements.txt (or requirements.ini) that will use pip to install other packages.

As far as the example goes, I would probably make a couple changes, though they are very minor:

Syntax: Select all

# Python Imports
from collections import defaultdict

# SourcePython imports
from players.entity import PlayerEntity
from players.helpers import index_from_userid

from weapons.entity import WeaponEntity

from entities.constants import RenderMode

from events import Event
from colors import Color

# create a dictionary
iProPlayer = defaultdict(lambda: None)


@Event
def player_spawn(game_event):
eventery(game_event.get_int('userid'))

@Event
def post_inventory_application(game_event):
eventery(game_event.get_int('userid'))

def eventery(userid):
if iProPlayer[userid] is not None:
set_weapon_invis(userid, iProPlayer[userid])

def set_weapon_invis(userid, alpha):
index = index_from_userid(userid)
player = PlayerEntity(userid)

alpha = max(min(alpha, 255), 0)

for weapon_index in player.weapon_indexes():
entity = WeaponEntity(weapon_index)
entity.render_mode = RenderMode.TRANS_COLOR
entity.color = Color(150, 150, 150, alpha)


Also, <Entity>.color currently is bugged. We are working on that issue and it should be fixed relatively soon.

As for your IsValidClient function, I am certain we have the capabilities to get all that information. I am just not sure how necessary all of those checks really are. To get a property, we have <Entity>.get_property_<type> functions. So, for m_bIsCoaching, you would just use:

Syntax: Select all

player.get_property_bool('tflocaldata.m_bIsCoaching')
Image
nergal
Member
Posts: 57
Joined: Sun Mar 15, 2015 2:58 pm

Postby nergal » Mon Jun 01, 2015 3:54 pm

alright FINAL question before I install S.P on all of my servers..... :3

Is there inter-plugin communication? If yes, how does it work?
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Mon Jun 01, 2015 6:34 pm

You can do that a couple different ways. It is highly recommended to at least use the first way to verify that the other plugin is loaded:

Syntax: Select all

from core.manager import core_plugin_manager

test = core_plugin_manager.get_plugin_instance('test')

if test is None:
raise



Syntax: Select all

from test.test import some_object
Image
necavi
Developer
Posts: 129
Joined: Wed Jan 30, 2013 9:51 pm

Postby necavi » Mon Jun 01, 2015 7:03 pm

Relatedly, are there any plans for some form of events through the plugin manager?
nergal
Member
Posts: 57
Joined: Sun Mar 15, 2015 2:58 pm

Postby nergal » Mon Jun 01, 2015 8:52 pm

satoon101 wrote:You can do that a couple different ways. It is highly recommended to at least use the first way to verify that the other plugin is loaded:

Syntax: Select all

from core.manager import core_plugin_manager

test = core_plugin_manager.get_plugin_instance('test')

if test is None:
raise



Syntax: Select all

from test.test import some_object


Wow, so basically you just call a plugin by filename and it can use anything from that plugin?

No natives registration or global forward making like in SourceMod?
stonedegg
Senior Member
Posts: 141
Joined: Sun Aug 12, 2012 11:45 am

Postby stonedegg » Mon Jun 01, 2015 9:23 pm

nergal wrote:
Wow, so basically you just call a plugin by filename and it can use anything from that plugin?

No natives registration or global forward making like in SourceMod?


Yes. :)
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Jun 02, 2015 4:01 am

necavi wrote:Relatedly, are there any plans for some form of events through the plugin manager?


I guess I am not fully sure what you are asking here. Do you mean are we going to create events based off of loading/unloading plugins?


nergal wrote:Wow, so basically you just call a plugin by filename and it can use anything from that plugin?

No natives registration or global forward making like in SourceMod?


This is Python, that sort of interface is already built-in. And, we do not want to have each individual plugin in its own environment.
Image
nergal
Member
Posts: 57
Joined: Sun Mar 15, 2015 2:58 pm

Postby nergal » Tue Jun 02, 2015 11:54 am

I'm also going to assume that the full Python std lib is 100% ready to use?
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Postby L'In20Cible » Tue Jun 02, 2015 12:27 pm

Indeed!
necavi
Developer
Posts: 129
Joined: Wed Jan 30, 2013 9:51 pm

Postby necavi » Tue Jun 02, 2015 2:29 pm

nergal
Member
Posts: 57
Joined: Sun Mar 15, 2015 2:58 pm

Postby nergal » Wed Jun 03, 2015 12:55 am

User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Wed Jun 03, 2015 1:00 am

There is a link to the wiki in the top bar. The wiki is not complete, as many features are not currently documented. If you or anyone else wishes to help document, please ask and we will get you set up.

http://wiki.sourcepython.com/pages/Main_Page
Image
nergal
Member
Posts: 57
Joined: Sun Mar 15, 2015 2:58 pm

Postby nergal » Thu Jun 04, 2015 2:20 am

sorry one more question.

Can source.py use compiled python files aka .pyc ?
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Thu Jun 04, 2015 3:02 am

In what capacity?

We certainly do not advocate for pre-compiled files. Our online Plugin Manager (where plugins will eventually be hosted), will not allow .pyc files to be included. Our "sp load" is designed so that if the primary .py file for the plugin is not included, it will not load.
Image
User avatar
BackRaw
Senior Member
Posts: 537
Joined: Sun Jul 15, 2012 1:46 am
Location: Germany
Contact:

Postby BackRaw » Thu Jun 04, 2015 12:17 pm

I think you can compile .pyc files for use in your .py plugin. For example

Syntax: Select all

# SP import
from events import Event

# your compiled .pyc import
from mypyc import SomeClass


@Event
def player_say(game_event):
some_object = SomeClass(game_event.get_int('userid'))

# do something here lol

Am I right? :D
My Github repositories:

Source.Python: https://github.com/backraw
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Thu Jun 04, 2015 12:54 pm

Yes, you could do that, but what's the point? You can easily decompile it back to a *.py file. Moreover, we want to encourage people to make their code public.
User avatar
Mahi
Senior Member
Posts: 236
Joined: Wed Aug 29, 2012 8:39 pm
Location: Finland

Postby Mahi » Thu Jun 04, 2015 1:20 pm

Not to mention, if you compile your code to .pyc on a linux and try to run the same code on windows, won't work. Same for 32-bit vs 64-bit.

Correct me if I'm wrong?

Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 13 guests