Raised This Month: $ Target: $400
 0% 

[TF2] TF2 Item DB (replaces tf2itemsinfo)


Post New Thread Reply   
 
Thread Tools Display Modes
bottiger
AlliedModders Donor
Join Date: Dec 2010
Old 08-28-2015 , 19:21   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #61

Quote:
Originally Posted by xXDeathreusXx View Post
Good news, I got it working with TF2IDB first try

However, I needed to make a custom version of TF2IDB, so you'll need that too

I'll also include the version of Bot Weapon Randomizer I have, but I won't give support on how to set it up, look on it's own thread for that, the plugin is a different name, but it uses everything the original has

If anyone knows of a different plugin that can retrieve the number of attributes an item has efficiently, let me know, Friagram deleted everything related to ItemsAPI, and I currently use 1 function in it for the weapon randomizer, ItemsApi_GetNumAttributes

There's absolutely no reason for you to make a custom version of tf2idb.

You can get the number of attributes an item has by doing this.

Code:
decl aid[TF2IDB_MAX_ATTRIBUTES];
decl Float:values[TF2IDB_MAX_ATTRIBUTES];
new attributes = TF2IDB_GetItemAttributes(123, aid, values);
There's a bit of boilerplate here, but you can wrap this in a function and it shouldn't be too much slower if for some reason you only need to know how many attributes an item has and not what the actual contents are.
__________________

Last edited by bottiger; 08-28-2015 at 19:32.
bottiger is offline
xXDeathreusXx
Veteran Member
Join Date: Mar 2013
Location: pPlayer->GetOrigin();
Old 08-28-2015 , 20:35   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #62

Quote:
Originally Posted by bottiger View Post
There's absolutely no reason for you to make a custom version of tf2idb.
For reasons of I'm not good with SQL, I did it for my own personal use.


Quote:
Originally Posted by bottiger View Post
You can get the number of attributes an item has by doing this.

Code:
decl aid[TF2IDB_MAX_ATTRIBUTES];
decl Float:values[TF2IDB_MAX_ATTRIBUTES];
new attributes = TF2IDB_GetItemAttributes(123, aid, values);
I was trying to wrap my head around that function for some time, I could never get it to work correctly, so, thanks for this.


Quote:
Originally Posted by bottiger View Post
There's a bit of boilerplate here, but you can wrap this in a function and it shouldn't be too much slower if for some reason you only need to know how many attributes an item has and not what the actual contents are.
This means it returns the number of attributes an item if supposed to have, and won't return what it has, yeah? That's okay, that's what I need that for
__________________
Plugins|Profile
Requests closed

I'm a smartass by nature, get used to it

Last edited by xXDeathreusXx; 08-28-2015 at 20:56.
xXDeathreusXx is offline
bottiger
AlliedModders Donor
Join Date: Dec 2010
Old 08-28-2015 , 21:58   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #63

Quote:
Originally Posted by xXDeathreusXx View Post
For reasons of I'm not good with SQL, I did it for my own personal use.




I was trying to wrap my head around that function for some time, I could never get it to work correctly, so, thanks for this.




This means it returns the number of attributes an item if supposed to have, and won't return what it has, yeah? That's okay, that's what I need that for
People should not be using 10 different versions of tf2idb because they don't know how to use SQL. Unless I provided a native that doesn't take SQL, you cannot avoid SQL. The natives are all using SQL underneath.

The native fills 2 arrays with the attribute id and the value. And the number that is returned is the number of attributes the item has.
__________________
bottiger is offline
xXDeathreusXx
Veteran Member
Join Date: Mar 2013
Location: pPlayer->GetOrigin();
Old 08-29-2015 , 00:07   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #64

Quote:
Originally Posted by bottiger View Post
People should not be using 10 different versions of tf2idb because they don't know how to use SQL. Unless I provided a native that doesn't take SQL, you cannot avoid SQL. The natives are all using SQL underneath.

The native fills 2 arrays with the attribute id and the value. And the number that is returned is the number of attributes the item has.
If you look at it, it does use SQL for everything
__________________
Plugins|Profile
Requests closed

I'm a smartass by nature, get used to it
xXDeathreusXx is offline
bottiger
AlliedModders Donor
Join Date: Dec 2010
Old 10-07-2015 , 16:50   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #65

The database generator has been updated to support the new changes made by Valve.

Please redownload tf2idb.zip and replace tf2idb.py and run it to get a new database.

The database generator has also been upgraded so failure to parse a new schema will not result in an empty database.

A new table "tf2idb_capabilities" has been created with the columns ("id" INTEGER NOT NULL , "capability" TEXT NOT NULL ). You may use TF2IDB_FindItemCustom to access this table.
__________________
bottiger is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 11-04-2015 , 00:13   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #66

I had no experience in python, so I went to lynda and watched "Up and Running with Python" :V

I had to make a little modification to allow system variables (since I run my local server for lan parties out of an external hard drive sometimes) in order to not modify the code a lot.

Code:
import os
TF_ENV_VAR = os.environ[r'TF2SERVER'].replace("\\", "/")
TF_FOLDER = TF_ENV_VAR + r'\tf2_dedicated_server\tf'.replace("\\", "/")
print (TF_FOLDER)
#TF_FOLDER = r'D:\Steam\SteamApps\common\Team Fortress 2\tf\'
ITEMS_GAME = TF_FOLDER + r'\scripts\items\items_game.txt'.replace("\\", "/")
DB_FILE = TF_FOLDER + r'\addons\sourcemod\data\sqlite\tf2idb.sq3'.replace("\\", "/")
and a print at the bottom

Code:
print('Completado :D') #spanish pls
Also I made it run every time I run the update script for the server
"update.bat"
Code:
@echo off
title update.bat
steamcmd.exe +runscript tf2_ds.txt
timeout 2
tf2_dedicated_server\tf\tf2idb\tf2idb.py
timeout 2
"tf2_ds.txt"
Code:
@ShutdownOnFailedCommand 1
@NoPromptForPassword 1
login anonymous
force_install_dir "TF2_Dedicated_Server"
app_update 232250
quit
I just setted everithing up, didn't make a plugin that uses this yet, but I am planning in using it for my Taunt Menu plugin.

fakuivan is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 11-04-2015 , 00:15   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #67

BTW, didn't work on Python 3.5.0
fakuivan is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 11-06-2015 , 00:16   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #68

I added a few lines to the db generator to make this plguin compatible with a future release.

I am currently working on a pluign that loads all the tf2 translation files to make a database with keys like "#TF_Weapon_Necro_Smasher" and values for spanish "El Necromachacador", "Kusliga klubban" for sweeden, and so on.

Code:
def resolve_prefabs(item):
	prefabs = item.get('prefab')
	if prefabs:
		prefab_aggregate = {}
		for prefab in prefabs.split():
			prefab_data = data['prefabs'][prefab]
			prefab_data = resolve_prefabs(prefab_data.copy())
			prefab_aggregate.update(prefab_data)
		prefab_aggregate.update(item)
		item = prefab_aggregate
	return item

with open(ITEMS_GAME) as f:
	data = vdf.parse(f)
	data = data['items_game']

db = sqlite3.connect(DB_FILE)
dbc = db.cursor()

dbc.execute('DROP TABLE IF EXISTS new_tf2idb_class')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_item_attributes')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_item')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_particles')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_equip_conflicts')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_equip_regions')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_capabilities')

dbc.execute('CREATE TABLE "new_tf2idb_class" ("id" INTEGER NOT NULL , "class" TEXT NOT NULL , PRIMARY KEY ("id", "class"))')
dbc.execute('CREATE TABLE "new_tf2idb_item_attributes" ("id" INTEGER NOT NULL , "attribute" INTEGER NOT NULL , "value" TEXT NOT NULL, PRIMARY KEY ("id", "attribute") )')
dbc.execute('CREATE TABLE "new_tf2idb_item" ('
	'"id" INTEGER PRIMARY KEY  NOT NULL ,'
	'"name" TEXT NOT NULL,'
	'"item_name" TEXT NOT NULL,' #HERE
	'"class" TEXT NOT NULL,'
	'"slot" TEXT,'
	'"quality" TEXT NOT NULL,'
	'"tool_type" TEXT,'
	'"min_ilevel" INTEGER,'
	'"max_ilevel" INTEGER,'
	'"baseitem" INTEGER,'
	'"holiday_restriction" TEXT,'
	'"has_string_attribute" INTEGER'
	')'
)
dbc.execute('CREATE TABLE "new_tf2idb_particles" ("id" INTEGER PRIMARY KEY  NOT NULL , "name" TEXT NOT NULL )')
dbc.execute('CREATE TABLE "new_tf2idb_equip_conflicts" ("name" TEXT NOT NULL , "region" TEXT NOT NULL , PRIMARY KEY ("name", "region"))')
dbc.execute('CREATE TABLE "new_tf2idb_equip_regions" ("id" INTEGER NOT NULL , "region" TEXT NOT NULL , PRIMARY KEY ("id", "region"))')
dbc.execute('CREATE TABLE "new_tf2idb_capabilities"  ("id" INTEGER NOT NULL , "capability" TEXT NOT NULL )')

nonce = int(time.time())
dbc.execute('CREATE INDEX "tf2idb_item_attributes_%i" ON "new_tf2idb_item_attributes" ("attribute" ASC)' % nonce)
dbc.execute('CREATE INDEX "tf2idb_class_%i" ON "new_tf2idb_class" ("class" ASC)' % nonce)
dbc.execute('CREATE INDEX "tf2idb_item_%i" ON "new_tf2idb_item" ("slot" ASC)' % nonce)

# particles
for particle_type,particle_list in data['attribute_controlled_attached_particles'].items():
	for k,v in particle_list.items():
		dbc.execute('INSERT INTO new_tf2idb_particles (id,name) VALUES (?,?)', (k, v['system']) )

# attributes
attribute_type = {}
for k,v in data['attributes'].items():
	at = v.get('attribute_type')
	if at:
		atype = at
	else:
		if v.get('stored_as_integer'):
			atype = 'integer'
		else:
			atype = 'float'
	attribute_type[v['name']] = (k, atype)

# conflicts
for k,v in data['equip_conflicts'].items():
	for region in v.keys():
		dbc.execute('INSERT INTO new_tf2idb_equip_conflicts (name,region) VALUES (?,?)', (k, region))

# items
for id,v in data['items'].iteritems():
	if id == 'default':
		continue
	i = resolve_prefabs(v)
	baseitem = 'baseitem' in i

	try:
		tool = None
		if 'tool' in i:
			tool = i['tool'].get('type')

		has_string_attribute = False
		if 'attributes' in i:
			for name,info in i['attributes'].iteritems():
				aid,atype = attribute_type[name]
				if atype == 'string':
					has_string_attribute = True
				dbc.execute('INSERT INTO new_tf2idb_item_attributes (id,attribute,value) VALUES (?,?,?)', (id,aid,info['value']))

		dbc.execute('INSERT INTO new_tf2idb_item '
			'(id,name,item_name,class,slot,quality,tool_type,min_ilevel,max_ilevel,baseitem,holiday_restriction,has_string_attribute) '
			'VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', #HERE too, added one ?
			(id,i['name'],i.get('item_name'),i['item_class'],i.get('item_slot'),i.get('item_quality', ''), tool, i.get('min_ilevel'), i.get('max_ilevel'),baseitem,#HERE ,i.get('item_name')
				i.get('holiday_restriction'), has_string_attribute)
		)

		if 'used_by_classes' in i:
			for prof in i['used_by_classes'].keys():
				dbc.execute('INSERT INTO new_tf2idb_class (id,class) VALUES (?,?)', (id, prof))

		region_field = i.get('equip_region') or i.get('equip_regions')
		if region_field:
			if type(region_field) is str:
				region_field = {region_field: 1}
			for region in region_field.keys():
				dbc.execute('INSERT INTO new_tf2idb_equip_regions (id,region) VALUES (?,?)', (id, region))

		# capabilties
		for capabilty in i.get('capabilities', []):
			dbc.execute('INSERT INTO new_tf2idb_capabilities (id,capability) VALUES (?,?)', (id, name))

	except:
		traceback.print_exc()
		print(id)
		raise

def replace_table(name):
	dbc.execute('DROP TABLE IF EXISTS %s' % name)
	dbc.execute('ALTER TABLE new_%s RENAME TO %s' % (name,name))

replace_table('tf2idb_class')
replace_table('tf2idb_item_attributes')
replace_table('tf2idb_item')
replace_table('tf2idb_particles')
replace_table('tf2idb_equip_conflicts')
replace_table('tf2idb_equip_regions')
replace_table('tf2idb_capabilities')

dbc.execute('VACUUM')
db.commit()
print('Completado :D') #silli spanish message
drop the code in an ide an look for the comments to see the changes, I just added a column.

it would be nice if you could add these lines to the release, just saying

fakuivan is offline
fakuivan
Senior Member
Join Date: Nov 2015
Old 11-08-2015 , 21:02   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #69

[FIX] Python 3.5

The method dict.iteritems is no longer valid since 3.x launched, dict.items is the equivalent in 3.x, Here are the small changes to the code (2 instances)

Code:
import vdf
import sqlite3
import traceback
import time

def resolve_prefabs(item):
	prefabs = item.get('prefab')
	if prefabs:
		prefab_aggregate = {}
		for prefab in prefabs.split():
			prefab_data = data['prefabs'][prefab]
			prefab_data = resolve_prefabs(prefab_data.copy())
			prefab_aggregate.update(prefab_data)
		prefab_aggregate.update(item)
		item = prefab_aggregate
	return item

with open(ITEMS_GAME) as f:
	data = vdf.parse(f)
	data = data['items_game']

db = sqlite3.connect(DB_FILE)
dbc = db.cursor()

dbc.execute('DROP TABLE IF EXISTS new_tf2idb_class')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_item_attributes')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_item')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_particles')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_equip_conflicts')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_equip_regions')
dbc.execute('DROP TABLE IF EXISTS new_tf2idb_capabilities')

dbc.execute('CREATE TABLE "new_tf2idb_class" ("id" INTEGER NOT NULL , "class" TEXT NOT NULL , PRIMARY KEY ("id", "class"))')
dbc.execute('CREATE TABLE "new_tf2idb_item_attributes" ("id" INTEGER NOT NULL , "attribute" INTEGER NOT NULL , "value" TEXT NOT NULL, PRIMARY KEY ("id", "attribute") )')
dbc.execute('CREATE TABLE "new_tf2idb_item" ('
	'"id" INTEGER PRIMARY KEY  NOT NULL ,'
	'"name" TEXT NOT NULL,'
	'"item_name" TEXT NOT NULL,'
	'"class" TEXT NOT NULL,'
	'"slot" TEXT,'
	'"quality" TEXT NOT NULL,'
	'"tool_type" TEXT,'
	'"min_ilevel" INTEGER,'
	'"max_ilevel" INTEGER,'
	'"baseitem" INTEGER,'
	'"holiday_restriction" TEXT,'
	'"has_string_attribute" INTEGER'
	')'
)
dbc.execute('CREATE TABLE "new_tf2idb_particles" ("id" INTEGER PRIMARY KEY  NOT NULL , "name" TEXT NOT NULL )')
dbc.execute('CREATE TABLE "new_tf2idb_equip_conflicts" ("name" TEXT NOT NULL , "region" TEXT NOT NULL , PRIMARY KEY ("name", "region"))')
dbc.execute('CREATE TABLE "new_tf2idb_equip_regions" ("id" INTEGER NOT NULL , "region" TEXT NOT NULL , PRIMARY KEY ("id", "region"))')
dbc.execute('CREATE TABLE "new_tf2idb_capabilities"  ("id" INTEGER NOT NULL , "capability" TEXT NOT NULL )')

nonce = int(time.time())
dbc.execute('CREATE INDEX "tf2idb_item_attributes_%i" ON "new_tf2idb_item_attributes" ("attribute" ASC)' % nonce)
dbc.execute('CREATE INDEX "tf2idb_class_%i" ON "new_tf2idb_class" ("class" ASC)' % nonce)
dbc.execute('CREATE INDEX "tf2idb_item_%i" ON "new_tf2idb_item" ("slot" ASC)' % nonce)

# particles
for particle_type,particle_list in data['attribute_controlled_attached_particles'].items():
	for k,v in particle_list.items():
		dbc.execute('INSERT INTO new_tf2idb_particles (id,name) VALUES (?,?)', (k, v['system']) )

# attributes
attribute_type = {}
for k,v in data['attributes'].items():
	at = v.get('attribute_type')
	if at:
		atype = at
	else:
		if v.get('stored_as_integer'):
			atype = 'integer'
		else:
			atype = 'float'
	attribute_type[v['name']] = (k, atype)

# conflicts
for k,v in data['equip_conflicts'].items():
	for region in v.keys():
		dbc.execute('INSERT INTO new_tf2idb_equip_conflicts (name,region) VALUES (?,?)', (k, region))

# items
for id,v in data['items'].items(): #HERE before (for id,v in data['items'].iteritems():)
	if id == 'default':
		continue
	i = resolve_prefabs(v)
	baseitem = 'baseitem' in i

	try:
		tool = None
		if 'tool' in i:
			tool = i['tool'].get('type')

		has_string_attribute = False
		if 'attributes' in i:
			for name,info in i['attributes'].items(): #HERE before (for name,info in i['attributes'].iteritems():)
				aid,atype = attribute_type[name]
				if atype == 'string':
					has_string_attribute = True
				dbc.execute('INSERT INTO new_tf2idb_item_attributes (id,attribute,value) VALUES (?,?,?)', (id,aid,info['value']))

		dbc.execute('INSERT INTO new_tf2idb_item '
			'(id,name,item_name,class,slot,quality,tool_type,min_ilevel,max_ilevel,baseitem,holiday_restriction,has_string_attribute) '
			'VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', 
			(id,i['name'],i.get('item_name'),i['item_class'],i.get('item_slot'),i.get('item_quality', ''), tool, i.get('min_ilevel'), i.get('max_ilevel'),baseitem,
				i.get('holiday_restriction'), has_string_attribute)
		)

		if 'used_by_classes' in i:
			for prof in i['used_by_classes'].keys():
				dbc.execute('INSERT INTO new_tf2idb_class (id,class) VALUES (?,?)', (id, prof))

		region_field = i.get('equip_region') or i.get('equip_regions')
		if region_field:
			if type(region_field) is str:
				region_field = {region_field: 1}
			for region in region_field.keys():
				dbc.execute('INSERT INTO new_tf2idb_equip_regions (id,region) VALUES (?,?)', (id, region))

		# capabilties
		for capabilty in i.get('capabilities', []):
			dbc.execute('INSERT INTO new_tf2idb_capabilities (id,capability) VALUES (?,?)', (id, name))

	except:
		traceback.print_exc()
		print(id)
		raise

def replace_table(name):
	dbc.execute('DROP TABLE IF EXISTS %s' % name)
	dbc.execute('ALTER TABLE new_%s RENAME TO %s' % (name,name))

replace_table('tf2idb_class')
replace_table('tf2idb_item_attributes')
replace_table('tf2idb_item')
replace_table('tf2idb_particles')
replace_table('tf2idb_equip_conflicts')
replace_table('tf2idb_equip_regions')
replace_table('tf2idb_capabilities')

dbc.execute('VACUUM')
db.commit()
Instructions:
1. Open the tf2idb.py file with any plain text (Notepad++ recomended, you can use notepad.exe too)
2. Replace the lines where it says #HERE
3. Save it
4. Try it and let me know if it doesn't work
I am not the creator of the code, I just know python

Last edited by fakuivan; 11-08-2015 at 21:07.
fakuivan is offline
xXDeathreusXx
Veteran Member
Join Date: Mar 2013
Location: pPlayer->GetOrigin();
Old 11-09-2015 , 01:33   Re: [TF2] TF2 Item DB (replaces tf2itemsinfo)
Reply With Quote #70

Quote:
Originally Posted by fakuivan View Post
I am not the creator of the code, I just know python
Quote:
Originally Posted by fakuivan View Post
I had no experience in python, so I went to lynda and watched "Up and Running with Python" :V
K...

Good work nonetheless, I don't use 3.0+ but good to know there's a fix if I ever do
__________________
Plugins|Profile
Requests closed

I'm a smartass by nature, get used to it
xXDeathreusXx is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 06:40.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode