done in last month:
* crafting fixture update * efefays logic implementation done today: * added game.log log basics for the parser. * updated utf-8 headers.
This commit is contained in:
parent
e9e6adc823
commit
36c8914181
57
analyze.py
Normal file
57
analyze.py
Normal file
@ -0,0 +1,57 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Tool to analyze Logs in general.
|
||||
"""
|
||||
import os, sys, logging
|
||||
from logs.logfiles import LogFileResolver as LogFile
|
||||
from logs import combat, game, chat
|
||||
from logs.session import LogSessionCollector
|
||||
from logs.game import ClientInfo
|
||||
|
||||
# for windows its kinda this:
|
||||
settings = {'root_path': os.path.join(os.path.expanduser('~'),
|
||||
'Documents',
|
||||
'My Games',
|
||||
'StarConflict',),
|
||||
'logfiles': os.path.join(os.path.expanduser('~'),
|
||||
'Documents',
|
||||
'My Games',
|
||||
'StarConflict',
|
||||
'logs'
|
||||
)}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
coll = LogSessionCollector(os.path.join(os.path.expanduser('~'),
|
||||
'Documents', 'My Games', 'sc'))
|
||||
coll.collect_unique()
|
||||
#f = open('output.txt', 'w')
|
||||
rex = {}
|
||||
for logf in coll.sessions:
|
||||
logf.parse_files(['game.log',])
|
||||
print "Combat Log %s" % logf.idstr
|
||||
if logf.combat_log:
|
||||
for l in logf.combat_log.lines:
|
||||
if isinstance(l, dict):
|
||||
#print l
|
||||
pass
|
||||
else:
|
||||
if not l.unpack():
|
||||
rex[l.__class__.__name__] = rex.get(l.__class__.__name__, 0) + 1
|
||||
if not isinstance(l, combat.UserEvent):
|
||||
print l.values['log']
|
||||
if logf.game_log:
|
||||
for l in logf.game_log.lines:
|
||||
if isinstance(l, dict):
|
||||
pass
|
||||
else:
|
||||
if l.unpack():
|
||||
pass
|
||||
else:
|
||||
print l.values['log']
|
||||
# ClientInfo introspection for ping
|
||||
if isinstance(l, ClientInfo) and l.values.get('clinfo', '') == 'avgPing':
|
||||
print l.values
|
||||
# fix avgPing parsing!
|
||||
print rex
|
4
app.py
4
app.py
@ -1,5 +1,5 @@
|
||||
|
||||
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Main application functions.
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Backup Directories, Handle Files...
|
||||
"""
|
||||
|
@ -16,7 +16,7 @@
|
||||
"""
|
||||
#from win32com.shell import shell, shellcon
|
||||
import os, sys, logging
|
||||
from logs.logresolver import LogFileResolver as LogFile
|
||||
from logs.logfiles import LogFileResolver as LogFile
|
||||
from logs import combat
|
||||
|
||||
# for windows its kinda this:
|
||||
|
File diff suppressed because one or more lines are too long
@ -53,9 +53,9 @@ def generate_fixtures():
|
||||
data = []
|
||||
|
||||
ORES = [
|
||||
{'name': 'Tungsten ore', 'sell_price': 6600, 'icon': 'resource_tungsten_ore'},
|
||||
{'name': 'Osmium ore', 'sell_price': 4500, 'icon': 'resource_osmium_ore'},
|
||||
{'name': 'Silicon ore', 'sell_price': 600, 'icon': 'resource_silicon_ore'},
|
||||
{'name': 'Impure tungsten', 'sell_price': 6600, 'icon': 'resource_tungsten_ore'},
|
||||
{'name': 'Impure osmium', 'sell_price': 4500, 'icon': 'resource_osmium_ore'},
|
||||
{'name': 'Impure silicon', 'sell_price': 600, 'icon': 'resource_silicon_ore'},
|
||||
{'name': 'Vanadium', 'sell_price': 500, 'icon': 'resource_vanadium'},
|
||||
{'name': 'Crystal shard', 'sell_price': 3500, 'icon': 'resource_crystal_shard'},
|
||||
]
|
||||
@ -329,13 +329,13 @@ def generate_fixtures():
|
||||
{'item': 'Duplicator',
|
||||
'recipee': [(1, 'Processing Block'), (2,'Computing chip'), (2, 'Metal blank')]},
|
||||
{'item': 'Tungsten plate',
|
||||
'recipee': [(2, 'Tungsten ore'),]},
|
||||
'recipee': [(2, 'Impure tungsten'),]},
|
||||
{'item': 'Screened battery',
|
||||
'recipee': [(1, 'Tungsten plate'), (2, 'Computing chip')]},
|
||||
{'item': 'Osmium crystals',
|
||||
'recipee': [(1, 'Osmium ore'),]},
|
||||
'recipee': [(1, 'Impure osmium'),]},
|
||||
{'item': 'Pure Silicon',
|
||||
'recipee': [(1, 'Silicon ore'),]},
|
||||
'recipee': [(1, 'Impure silicon'),]},
|
||||
{'item': 'Computing chip',
|
||||
'recipee': [(1, 'Crystal shard'),]},
|
||||
{'item': 'Processing block',
|
||||
|
@ -90,6 +90,17 @@ class Item(models.Model):
|
||||
def crafting_used_in(self):
|
||||
return CraftingInput.objects.filter(item=self)
|
||||
|
||||
def parents(self):
|
||||
my_recipee = Crafting.objects.filter(output=self)
|
||||
if my_recipee.count():
|
||||
ci = CraftingInput.objects.filter(crafting=my_recipee).filter(primary=True)
|
||||
if ci.count():
|
||||
# ci.item is my parent
|
||||
ret = [ci[0].item]
|
||||
ret.extend(ci[0].item.parents())
|
||||
return ret
|
||||
return []
|
||||
|
||||
def get_full_name(self):
|
||||
if self.quality:
|
||||
return '%s (%s)' % (self.name, D_QUALITY.get(self.quality, ''))
|
||||
@ -122,8 +133,8 @@ class Crafting(models.Model):
|
||||
return 'Recipee for %s' % (self.output.name,)
|
||||
|
||||
class CraftingInput(models.Model):
|
||||
crafting = models.ForeignKey(Crafting)
|
||||
item = models.ForeignKey(Item)
|
||||
crafting = models.ForeignKey(Crafting) # the items you need.
|
||||
item = models.ForeignKey(Item) # the item you get.
|
||||
amount = models.IntegerField(default=1)
|
||||
primary = models.BooleanField(default=False, blank=True)
|
||||
|
||||
|
@ -68,6 +68,7 @@
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
<!-- Copyright notice: -->
|
||||
.arrowright {
|
||||
background: #2C2C2C;
|
||||
font-size: 12px;
|
||||
|
581
dj/scon/templates/scon/crafting/bbcode.txt
Normal file
581
dj/scon/templates/scon/crafting/bbcode.txt
Normal file
@ -0,0 +1,581 @@
|
||||
[quote name="FunkyDonut" post="271113" timestamp="1402589748"]
|
||||
This guide will only focus on the crafting system in the Invasion game mode. Please use the [url=http://forum.star-conflict.com/index.php?/topic/23371-invasion-introductory-guide/?p=269862][color=#0000cd]introductory guide[/color][/url], if you have general questions on the game mode itself, rather than the crafting system.
|
||||
[center] [/center]
|
||||
[center] [/center]
|
||||
[center][color=#008000][b]Special thanks go to [/b][/color][b][url=http://forum.star-conflict.com/index.php?/user/239042-g4borg/][color=#0000cd]g4borg[/color][/url][/b][color=#008000][b], who mostly provided the information![/b][/color][/center]
|
||||
|
||||
In the Invasion game mode, you will be able to find trophies floating around in space. Those trophies can be simply credits, artefacts or debris, which is sold autmatically once you used a drone/returned to the station. But you may also find ressources - mostly close to asteroids, but sometimes also in cargo transports, shipwrecks or stolen containers from other pilots, which you shot down. These ressources can be used to craft to usefull items, such as new and powerful modules, new types of ammunition or the valuable duplicators, which allow you to reconstruct your ship, if you have been destroyed once. Below, you will see a listing
|
||||
|
||||
[color=#ff0000][u][b]Concerning updates:[/b][/u][/color] Please write me a private message, if you have something to add, or if there is anything wrong. I will edit/update this guide as soon as possible.
|
||||
[indent=1] [/indent]
|
||||
[size=6][b]Ressources[/b][/size]
|
||||
[table][tr][th][b]Ressources[/b][/th][th][b][color=#ff8c00]Crafting result[/color]/[color=#8b4513]necessary ressources[/color][/b][/th][th][b]Used for...[/b][/th][/tr][tr]
|
||||
[td][b]Tungsten Ore[/b]
|
||||
[/td][td][b][color=#ff8c00]Tungsten Plate[/color]
|
||||
[color=#8b4513]Tungsten ore x 2[/color][/b]
|
||||
[/td][td]
|
||||
[LIST]
|
||||
[*]Screened battery (Tungsten plate)[/*]
|
||||
[*]Pirate "Orion" Targeting Complex V (Tungsten plate)[/*]
|
||||
[*]Pirate Engine Overcharge V (Tungsten plate)[/*]
|
||||
[*]Reverse Thruster V (Tungsten plate)[/*]
|
||||
[*]Alien Plasma Gun IV (Tungsten plate)[/*]
|
||||
[*]Alien Plasma Gun V (Tungsten plate)[/*]
|
||||
[*]Alien Assault Railgun IV (Tungsten plate)[/*]
|
||||
[*]Alien Assault Railgun V (Tungsten plate)[/*]
|
||||
[*]Alien Beam Cannon IV (Tungsten plate)[/*]
|
||||
[*]Alien Beam Cannon V (Tungsten plate)[/*]
|
||||
[/LIST]
|
||||
[/td][/tr][tr][td][b]Osmium ore[/b]
|
||||
[/td][td]
|
||||
[b][color=#ff8c00]Osmium crystals[/color]
|
||||
[color=#8b4513]Osmium ore x 1[/color][/b]
|
||||
[/td][td]
|
||||
[LIST]
|
||||
[*]Double Deflector (Osmium crystals)[/*]
|
||||
[*]Focusing Lens (Osmium crystals)[/*]
|
||||
[*]Pirate Engine Overcharge V (Osmium crystals)[/*]
|
||||
[*]Doomsday Missile (Osmium crystals)[/*]
|
||||
[/LIST]
|
||||
[indent=1][/td][/tr][tr][td][b]Silicon ore[/b]
|
||||
[/td][td]
|
||||
[b][color=#ff8c00]Pure Silicon[/color]
|
||||
[color=#8b4513]Silicon ore x 1[/color][/b][/indent]
|
||||
|
||||
[/td][td]
|
||||
[LIST]
|
||||
[*]Processing block (Pure Silicon)[/*]
|
||||
[*]Target Tracking Coprocessor III (Pure Silicon)[/*]
|
||||
[*]Explosive Shells (Pure Silicon)[/*]
|
||||
[*]Xenon Lamp (Pure Silicon)[/*]
|
||||
[/LIST]
|
||||
[indent=1][/td][/tr][tr][td][b]Vanadium[/b]
|
||||
[/td][td]
|
||||
[b][color=#ff8c00]Metal blank[/color]
|
||||
[color=#8b4513]Vanadium x 2[/color][/b][/indent]
|
||||
[/td][td]
|
||||
[LIST]
|
||||
[*]Duplicator (Metal blank)[/*]
|
||||
[*]Target Tracking Coprocessor III (Metal blank)[/*]
|
||||
[*]Explosive Shells (Metal blank)[/*]
|
||||
[*]Iridium Slugs (Metal blank)[/*]
|
||||
[*]A1MA IV (Metal blank)[/*]
|
||||
[*]Pirate Mass Shield Generator V (Metal blank)[/*]
|
||||
[*]Reverse Thruster III (Metal blank)[/*]
|
||||
[*]Reverse Thruster IV (Metal blank)[/*]
|
||||
[*]Alien Plasma Gun III (Metal blank)[/*]
|
||||
[*]Alien Assault Railgun III (Metal blank)[/*]
|
||||
[*]Alien Beam Cannon III (Metal blank)[/*]
|
||||
[*]Doomsday Missile (Metal blank)[/td][/*]
|
||||
[/LIST]
|
||||
[/tr][tr][td][b]Crystal shard[/b]
|
||||
[/td]
|
||||
[td]
|
||||
[b][color=#ff8c00]Computing chip[/color][/b]
|
||||
[color=#8b4513][b]Crystal shard x 1[/b][/color]
|
||||
|
||||
[/td]
|
||||
[td]
|
||||
[LIST]
|
||||
[*]Duplicator (Computing chip)[/*]
|
||||
[*]Screened battery (Computing chip)[/*]
|
||||
[*]Processing block (Computing chip)[/*]
|
||||
[*]Attack Drone (Computing chip)[/*]
|
||||
[*]Xenon Lamp (Computing chip)[/*]
|
||||
[*]Supercooled Charges (Computing chip)[/*]
|
||||
[*]Pirate "Orion" Targeting Complex V (Computing chip)[/*]
|
||||
[*]Pirate Mass Shield Generator V (Computing chip)[/*]
|
||||
[*]Reverse Thruster III (Computing chip)[/*]
|
||||
[*]Reverse Thruster IV (Computing chip)[/*]
|
||||
[*]Reverse Thruster V (Computing chip)[/*]
|
||||
[*]Doomsday Missile (Computing chip)[/*]
|
||||
[/LIST]
|
||||
[/td][/tr][tr][td][b]Osmium crystals[/b]
|
||||
[/td]
|
||||
[td]
|
||||
[b][color=#ff8c00]Double Deflector (Mk4)[/color][/b]
|
||||
[color=#8b4513][b]Osmium crystals x 1[/b][/color][/td]
|
||||
|
||||
[td]
|
||||
[LIST]
|
||||
[*]Focusing Lens[/*]
|
||||
[*]Pirate Engine Overcharge V[/*]
|
||||
[*]Doomsday Missile[/*]
|
||||
[/LIST]
|
||||
[/td][/tr][tr][td][b]Alien Monocrystal[/b]
|
||||
[/td][td]
|
||||
[b][color=#ff8c00]Attack Drone (Universal)[/color][/b]
|
||||
[color=#8b4513][b]Alien Monocrystal x 1[/b][/color]
|
||||
|
||||
[color=#8b4513][b]Computing chip x 1[/b][/color][/td][td]
|
||||
[LIST]
|
||||
[*]A1MA IV[/*]
|
||||
[*]Pirate "Orion" Targeting Complex V[/*]
|
||||
[*]Pirate Engine Overcharge V[/*]
|
||||
[*]Pirate Mass Shield Generator V[/*]
|
||||
[*]Reverse Thruster III[/*]
|
||||
[*]Reverse Thruster IV[/*]
|
||||
[*]Reverse Thruster V[/*]
|
||||
[*]Alien Plasma Gun III[/*]
|
||||
[*]Alien Plasma Gun IV[/*]
|
||||
[*]Alien Plasma Gun V[/*]
|
||||
[*]Alien Assault Railgun III[/*]
|
||||
[*]Alien Assault Railgun IV[/*]
|
||||
[*]Alien Assault Railgun V[/*]
|
||||
[*]Alien Beam Cannon III[/*]
|
||||
[*]Alien Beam Cannon IV[/*]
|
||||
[*]Alien Beam Cannon V[/*]
|
||||
[/LIST]
|
||||
[/td][/tr][tr]
|
||||
|
||||
[td][b]Tungsten plate[/b][/td][td]
|
||||
[b][color=#ff8c00]Screened battery[/color][/b]
|
||||
[color=#8b4513][b]Tungsten plate x 1[/b][/color]
|
||||
|
||||
[color=#8b4513][b]Computing chip x 2[/b][/color][/td]
|
||||
[td]
|
||||
[LIST]
|
||||
[*]Target Tracking Coprocessor III (Screened battery)[/*]
|
||||
[*]A1MA IV (Screened battery)[/*]
|
||||
[*]Reverse Thruster III (Screened battery)[/*]
|
||||
[*]Reverse Thruster IV (Screened battery)[/*]
|
||||
[*]Reverse Thruster V (Screened battery)[/*]
|
||||
[*]Alien Plasma Gun III (Screened battery)[/*]
|
||||
[*]Alien Plasma Gun IV (Screened battery)[/*]
|
||||
[*]Alien Plasma Gun V (Screened battery)[/*]
|
||||
[*]Alien Assault Railgun III (Screened battery)[/*]
|
||||
[*]Alien Assault Railgun IV (Screened battery)[/*]
|
||||
[*]Alien Assault Railgun V (Screened battery)[/*]
|
||||
[*]Alien Beam Cannon III (Screened battery)[/*]
|
||||
[*]Alien Beam Cannon IV (Screened battery)[/*]
|
||||
[*]Alien Beam Cannon V (Screened battery)[/*]
|
||||
[*]Pirate "Orion" Targeting Complex V[/*]
|
||||
[*]Pirate Engine Overcharge V[/*]
|
||||
[*]Reverse Thruster V[/*]
|
||||
[*]Alien Plasma Gun IV[/*]
|
||||
[*]Alien Plasma Gun V[/*]
|
||||
[*]Alien Assault Railgun IV[/*]
|
||||
[*]Alien Assault Railgun V[/*]
|
||||
[*]Alien Beam Cannon IV[/*]
|
||||
[*]Alien Beam Cannon V[/*]
|
||||
[/LIST]
|
||||
[/td][/tr][tr]
|
||||
[td][b]Screened battery[/b][/td][td]
|
||||
[b][color=#ff8c00]Target Tracking Coprocessor III[/color][/b]
|
||||
[color=#8b4513][b]Screened battery x 1[/b][/color]
|
||||
|
||||
[color=#8b4513][b]Metal blank x 7[/b][/color]
|
||||
[color=#8b4513][b]Pure Silicon x 5[/b][/color]
|
||||
[/td][td]
|
||||
[LIST]
|
||||
[*]A1MA IV[/*]
|
||||
[*]Reverse Thruster III[/*]
|
||||
[*]Reverse Thruster IV[/*]
|
||||
[*]Reverse Thruster V[/*]
|
||||
[*]Alien Plasma Gun III[/*]
|
||||
[*]Alien Plasma Gun IV[/*]
|
||||
[*]Alien Plasma Gun V[/*]
|
||||
[*]Alien Assault Railgun III[/*]
|
||||
[*]Alien Assault Railgun IV[/*]
|
||||
[*]Alien Assault Railgun V[/*]
|
||||
[*]Alien Beam Cannon III[/*]
|
||||
[*]Alien Beam Cannon IV[/*]
|
||||
[*]Alien Beam Cannon V[/*]
|
||||
[/LIST]
|
||||
[/td][/tr][tr][td][b]Pure Silicon[/b][/td]
|
||||
[td]
|
||||
[b][color=#ff8c00]Processing block[/color][/b]
|
||||
[color=#8b4513][b]Pure Silicon x 4[/b][/color]
|
||||
|
||||
[color=#8b4513][b]Computing chip x 2[/b][/color]
|
||||
[/td][td]
|
||||
[LIST]
|
||||
[*]Duplicator (Processing block)[/*]
|
||||
[*]A1MA IV (Processing block)[/*]
|
||||
[*]Pirate "Orion" Targeting Complex V (Processing block)[/*]
|
||||
[*]Pirate Engine Overcharge V (Processing block)[/*]
|
||||
[*]Pirate Mass Shield Generator V (Processing block)[/*]
|
||||
[*]Target Tracking Coprocessor III[/*]
|
||||
[*]Explosive Shells[/*]
|
||||
[*]Xenon Lamp[/*]
|
||||
[/LIST]
|
||||
[/td][/tr][tr]
|
||||
[td][b]Metal blank[/b][/td]
|
||||
[td]
|
||||
[b][color=#ff8c00]Explosive Shells (Mk4)[/color][/b]
|
||||
[color=#8b4513][b]Metal blank x 1[/b][/color]
|
||||
|
||||
[color=#8b4513][b]Pure Silicon x 2[/b][/color]
|
||||
[/td][td]
|
||||
[LIST]
|
||||
[*]Duplicator[/*]
|
||||
[*]Target Tracking Coprocessor III[/*]
|
||||
[*]Explosive Shells[/*]
|
||||
[*]Iridium Slugs[/*]
|
||||
[*]A1MA IV[/*]
|
||||
[*]Pirate Mass Shield Generator V[/*]
|
||||
[*]Reverse Thruster III[/*]
|
||||
[*]Reverse Thruster IV[/*]
|
||||
[*]Alien Plasma Gun III[/*]
|
||||
[*]Alien Assault Railgun III[/*]
|
||||
[*]Alien Beam Cannon III[/*]
|
||||
[*]Doomsday Missile[/*]
|
||||
[/LIST]
|
||||
[/td][/tr][tr]
|
||||
[td][b]Computing chip[/b][/td][td]
|
||||
[b][color=#ff8c00]Xenon Lamp (Mk4)[/color][/b]
|
||||
[color=#8b4513][b]Computing chip x 1[/b][/color]
|
||||
|
||||
[color=#8b4513][b]Pure Silicon x 1[/b][/color] [/td][td]
|
||||
[LIST]
|
||||
[*]Duplicator[/*]
|
||||
[*]Screened battery[/*]
|
||||
[*]Target Tracking Coprocessor III (Screened battery)[/*]
|
||||
[*]A1MA IV (Screened battery)[/*]
|
||||
[*]Reverse Thruster III (Screened battery)[/*]
|
||||
[*]Reverse Thruster IV (Screened battery)[/*]
|
||||
[*]Reverse Thruster V (Screened battery)[/*]
|
||||
[*]Alien Plasma Gun III (Screened battery)[/*]
|
||||
[*]Alien Plasma Gun IV (Screened battery)[/*]
|
||||
[*]Alien Plasma Gun V (Screened battery)[/*]
|
||||
[*]Alien Assault Railgun III (Screened battery)[/*]
|
||||
[*]Alien Assault Railgun IV (Screened battery)[/*]
|
||||
[*]Alien Assault Railgun V (Screened battery)[/*]
|
||||
[*]Alien Beam Cannon III (Screened battery)[/*]
|
||||
[*]Alien Beam Cannon IV (Screened battery)[/*]
|
||||
[*]Alien Beam Cannon V (Screened battery)[/*]
|
||||
[*]Processing block[/*]
|
||||
[*]Duplicator (Processing block)[/*]
|
||||
[*]A1MA IV (Processing block)[/*]
|
||||
[*]Pirate "Orion" Targeting Complex V (Processing block)[/*]
|
||||
[*]Pirate Engine Overcharge V (Processing block)[/*]
|
||||
[*]Pirate Mass Shield Generator V (Processing block)[/*]
|
||||
[*]Attack Drone[/*]
|
||||
[*]Xenon Lamp[/*]
|
||||
[*]Supercooled Charges[/*]
|
||||
[*]Pirate "Orion" Targeting Complex V[/*]
|
||||
[*]Pirate Mass Shield Generator V[/*]
|
||||
[*]Reverse Thruster III[/*]
|
||||
[*]Reverse Thruster IV[/*]
|
||||
[*]Reverse Thruster V[/*]
|
||||
[*]Doomsday Missile[/*]
|
||||
[/LIST]
|
||||
[/td][/tr]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[/table]
|
||||
|
||||
|
||||
[size=6][b]Known/Available Blueprints[/b][/size]
|
||||
|
||||
[indent=1][size=6][b][size=4][size=5][color=#008000]Important: [/color][/size][/size][/b][size=4][size=5]The ammunition-blueprints produce consumable items, which only last for one battle each! The same goes for duplicators and Doomsday missiles![/size][/size][/size][/indent]
|
||||
|
||||
[table][tr][th][b]Blueprints[/b][/th][th][color=#8b4513][b]Crafting parts[/b][/color][/th][th][b]Result[/b][/th][/tr][tr]
|
||||
[td][b]Focusing Lens[/b][/td][td]
|
||||
|
||||
[LIST]
|
||||
[*][b][color=#8b4513]Focusing Lens Blueprint x 1[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Osmium crystals x 1[/color][/b][/*]
|
||||
[/LIST]
|
||||
[/td][td]Focusing Lens Mk.4[/td][/tr][tr]
|
||||
[td][b]Iridium Slugs[/b][/td][td]
|
||||
|
||||
[LIST]
|
||||
[*][b][color=#8b4513]Iridium Slugs Blueprint x 1[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Metal blank x 1[/color][/b][/*]
|
||||
[/LIST]
|
||||
[/td][td]Iridium Slugs Mk.4[/td][/tr][tr]
|
||||
[td][b]Supercooled Charges[/b][/td][td]
|
||||
|
||||
[LIST]
|
||||
[*][b][color=#8b4513]Supercooled Charges Blueprint x 1[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Computing chip x 1[/color][/b][/*]
|
||||
[/LIST]
|
||||
[/td][td]Supercooled Charges Mk.4[/td][/tr][tr]
|
||||
[td][b]A1MA T4[/b][/td][td]
|
||||
|
||||
[LIST]
|
||||
[*][b][color=#8b4513]A1MA T4 Blueprint x 1[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Processing block x 2[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Metal blank x 14[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Screened battery x 2[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Alien Monocrystal x 20[/color][/b][/*]
|
||||
[/LIST]
|
||||
[/td][td]
|
||||
A1MA IV[/td][/tr][tr]
|
||||
[td][b]Orion-2 Targeting Complex[/b][/td][td]
|
||||
Pirate "Orion" Targeting Complex V (Pirate Mk4)
|
||||
|
||||
[LIST]
|
||||
[*][b][color=#8b4513]Orion-2 Targeting Complex Blueprint x 1[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Tungsten plate x 3[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Computing chip x 4[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Processing block x 2[/color][/b][/*]
|
||||
[*][b][color=#8b4513]Alien Monocrystal x 30[/color][/b][/*]
|
||||
[/LIST]
|
||||
[/td][td]Pirate "Orion" Targeting Complex V[/td][/tr][tr]
|
||||
[td][b]Engine Warp Overcharge[/b][/td][td]
|
||||
Pirate Engine Overcharge V (Pirate Mk4)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Engine Warp Overcharge Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Tungsten plate x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Osmium crystals x 2[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Processing block x 2[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 30[/b][/color][/*]
|
||||
[/LIST]
|
||||
[/td][td]Pirate Engine Overcharge V[/td][/tr][tr]
|
||||
[td][b]Mass Shield Energizer[/b][/td][td]
|
||||
Pirate Mass Shield Generator V (Pirate Mk4)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Mass Shield Energizer Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Metal blank x 10[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Computing chip x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Processing block x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 30[/b][/color][/*]
|
||||
[/LIST]
|
||||
[/td][td]Pirate Mass Shield Generator V[/td][/tr][tr]
|
||||
[td][b]Reverse Thruster T3[/b][/td][td]
|
||||
Reverse Thruster III (Mk1)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Reverse Thruster T3 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Metal blank x 7[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Computing chip x 4[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 15[/b][/color][/*]
|
||||
[/LIST]
|
||||
[/td][td]Reverse Thruster III[/td][/tr][tr]
|
||||
[td][b]Reverse Thruster T4[/b][/td][td]
|
||||
Reverse Thruster IV (Mk1)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Reverse Thruster T4 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Metal blank x 12[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 2[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Computing chip x 5[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 20[/b][/color][/*]
|
||||
[/LIST]
|
||||
[/td][td]Reverse Thruster IV[/td][/tr][tr][td][b]Reverse Thruster T5[/b][/td]
|
||||
[td]
|
||||
Reverse Thruster V (Mk1)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Reverse Thruster T5 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Tungsten plate x 7[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Computing chip x 6[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 30[/b][/color][/*]
|
||||
[/LIST]
|
||||
[/td][td]Reverse Thruster V[/td][/tr][tr]
|
||||
[td][b]Beam Cannon Prototype T3[/b][/td][td]
|
||||
Alien Beam Cannon III (Mk5)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Beam Cannon Prototype T3 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Beam Cannon III x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Metal blank x 6[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 30[/b][/color][/*]
|
||||
[/LIST]
|
||||
[/td][td]Alien Beam Cannon III[/td][/tr][tr]
|
||||
[td][b]Beam Cannon Prototype T4[/b][/td][td]
|
||||
Alien Beam Cannon IV (Mk5)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Beam Cannon Prototype T4 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Beam Cannon IV x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Tungsten plate x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 4[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 50[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
|
||||
[/td][td]Alien Beam Cannon IV[/td][/tr][tr]
|
||||
[td][b]Beam Cannon Prototype T5[/b][/td][td]
|
||||
Alien Beam Cannon V (Mk5)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Beam Cannon Prototype T5 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Beam Cannon V x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Tungsten plate x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 5[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 70[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
|
||||
[/td][td]Alien Beam Cannon V[/td][/tr][tr]
|
||||
[td][b]Assault Railgun Prototype T3[/b][/td][td]
|
||||
Alien Assault Railgun III (Mk5)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Assault Railgun Prototype T3 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Assault Railgun III x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Metal blank x 6[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 30[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
|
||||
[/td][td]
|
||||
Alien Assault Railgun III
|
||||
[/td][/tr][tr]
|
||||
[td][b]Assault Railgun Prototype T4[/b][/td][td]
|
||||
Alien Assault Railgun IV (Mk5)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Assault Railgun Prototype T4 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Assault Railgun IV x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Tungsten plate x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 4[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 50[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
|
||||
[/td][td]Alien Assault Railgun IV[/td][/tr][tr]
|
||||
[td][b]Assault Railgun Prototype T5[/b][/td][td]
|
||||
Alien Assault Railgun V (Mk5)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Assault Railgun Prototype T5 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Assault Railgun V x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Tungsten plate x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 5[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 70[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
|
||||
[/td][td]Alien Assault Railgun V[/td][/tr][tr]
|
||||
[td][b]Plasma Gun Prototype T3[/b][/td][td]
|
||||
Alien Plasma Gun III (Mk5)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Plasma Gun Prototype T3 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Plasma Gun III x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Metal blank x 6[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 30[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
|
||||
[/td][td]Alien Plasma Gun III[/td][/tr][tr]
|
||||
[td][b]Plasma Gun Prototype T4[/b][/td][td]
|
||||
Alien Plasma Gun IV (Mk5)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Plasma Gun Prototype T4 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Plasma Gun IV x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Tungsten plate x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 4[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 50[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
|
||||
[/td][td]Alien Plasma Gun IV[/td][/tr][tr]
|
||||
[td][b]Plasma Gun Prototype T5[/b][/td][td]
|
||||
Alien Plasma Gun V (Mk5)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Plasma Gun Prototype T5 Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Plasma Gun V x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Tungsten plate x 3[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Screened battery x 5[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Alien Monocrystal x 70[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
|
||||
[/td][td]Alien Plasma Gun V[/td][/tr][tr]
|
||||
[td][b]Doomsday Missile[/b][/td][td]
|
||||
Doomsday Missile (Mk1)
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Doomsday Missile Blueprint x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Osmium crystals x 2[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Computing chip x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Metal blank x 1[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
|
||||
[/td][td]Doomsday Missile[/td][/tr][tr]
|
||||
[td][b]Duplicator[/b][/td][td]
|
||||
Duplicator
|
||||
|
||||
[LIST]
|
||||
[*][color=#8b4513][b]Processing block x 1[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Computing chip x 2[/b][/color][/*]
|
||||
[*][color=#8b4513][b]Metal blank x 2[/b][/color][/*]
|
||||
[/LIST]
|
||||
|
||||
[/td][td]Duplicator[/td][/tr]
|
||||
[/table]
|
||||
[/quote]
|
||||
|
||||
|
||||
|
||||
|
||||
[b][font=arial, sans-serif][size=14]The Color Code[/size][/font][/b]
|
||||
[b][color=#595959][font=arial, sans-serif][size=12]Gray [/size][/font][/color][/b][font=arial, sans-serif][size=12]– Materials of this color will be raw resources. [/size][/font]
|
||||
[b][color=#00b050][font=arial, sans-serif][size=12]Green [/size][/font][/color][/b][font=arial, sans-serif][size=12]– Materials here have been crafted once since being a raw resource.[/size][/font]
|
||||
[b][color=#1f497d][font=arial, sans-serif][size=12]Blue [/size][/font][/color][/b][font=arial, sans-serif][size=12]– Materials here have been at most crafted twice since being a raw resource.[/size][/font]
|
||||
[b][color=#7030a0][font=arial, sans-serif][size=12]Purple [/size][/font][/color][/b][font=arial, sans-serif][size=12]– Materials here have been at most crafted three times since being a raw resource.[/size][/font]
|
||||
[b][color=#e46c0a][font=arial, sans-serif][size=12]Orange [/size][/font][/color][/b][font=arial, sans-serif][size=12]– Materials here have been at most crafted four times since being a raw resource.[/size][/font]
|
||||
[b][color=#ff3399][font=arial, sans-serif][size=12]Pink [/size][/font][/color][/b][font=arial, sans-serif][size=12]– Materials here have been at most crafted five times since being a raw resource (I doubt this is even possible but just in case).[/size][/font]
|
||||
|
||||
|
||||
[table]
|
||||
[tr][th][b][font=arial, sans-serif][size=12]Crafting Result [/size][/font][/b]
|
||||
[b][font=arial, sans-serif][size=12](the components you want)[/size][/font][/b][/th][th][b][font=arial, sans-serif][size=12]Prerequisite Materials [/size][/font][/b]
|
||||
[b][font=arial, sans-serif][size=12](what you need to get the result)[/size][/font][/b][/th][/tr]
|
||||
[tr]
|
||||
[td][b][color=#595959][font=arial, sans-serif][size=12]Crystal Shard[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]N/A[/size][/font][/td]
|
||||
[/tr]
|
||||
[tr]
|
||||
[td][b][color=#595959][font=arial, sans-serif][size=12]Osmium Ore[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]N/A[/size][/font][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#595959][font=arial, sans-serif][size=12]Silicon Ore[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]N/A[/size][/font][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#595959][font=arial, sans-serif][size=12]Tungsten Ore[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]N/A[/size][/font][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#595959][font=arial, sans-serif][size=12]Vanadium (Ore)[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]N/A[/size][/font][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#595959][font=arial, sans-serif][size=12]Alien Monocrystal[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]N/A [/size][/font][font=arial, sans-serif](Although this is a component you cannot craft it using raw resources.)[/size][/font][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#00b050][font=arial, sans-serif][size=12]Computing Chip[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]1x [/size][/font][b][color=#595959]Crystal Shard[/color][/b][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#00b050][font=arial, sans-serif][size=12]Metal Blank[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]2x [/size][/font][b][color=#595959]Vanadium (Ore)[/color][/b][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#00b050][font=arial, sans-serif][size=12]Osmium Crystals[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]1x [/size][/font][b][color=#595959]Osmium Ore[/color][/b][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#00b050][font=arial, sans-serif][size=12]Pure Silicon[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]1x [/size][/font][b][color=#595959]Silicon Ore[/color][/b][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#00b050][font=arial, sans-serif][size=12]Tungsten Plate[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]2x [/size][/font][b][color=#595959]Tungsten Ore[/color][/b][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#1f497d][font=arial, sans-serif][size=12]Processing Block[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]4x [/size][/font][b][color=#00b050]Pure Silicon[/color][/b]
|
||||
[font=arial, sans-serif]2x [/size][/font][b][color=#00b050]Computing Chip[/color][/b][/td]
|
||||
[/tr][tr]
|
||||
[td][b][color=#1f497d][font=arial, sans-serif][size=12]Screened Battery[/size][/font][/color][/b][/td]
|
||||
[td][font=arial, sans-serif]1x [/size][/font][b][color=#00b050]Tungsten Plate[/color][/b]
|
||||
[font=arial, sans-serif]2x [/size][/font][b][color=#00b050]Computing Chip[/color][/b][/td]
|
||||
[/tr]
|
||||
[/table]
|
||||
|
41
dj/scon/templates/scon/crafting/forum.html
Normal file
41
dj/scon/templates/scon/crafting/forum.html
Normal file
@ -0,0 +1,41 @@
|
||||
{% extends "scon/base.html" %}
|
||||
|
||||
{% block context %}
|
||||
<h1>Forum</h1>
|
||||
|
||||
|
||||
<code>
|
||||
[table][tr][th]Item[/th][th]Produces[/th][/tr]
|
||||
{% for item in items %}
|
||||
{% if item.primary_recipee %}
|
||||
[tr]
|
||||
{% with item.primary_recipee as recipee %}
|
||||
|
||||
[td]
|
||||
{{ item.name }}
|
||||
[/td]
|
||||
|
||||
|
||||
|
||||
|
||||
[td]
|
||||
{{ recipee.output.name }}
|
||||
[LIST]
|
||||
{% for ingredient in recipee.ingredients %}
|
||||
{% if ingredient.item != item %}
|
||||
[*]{{ ingredient.amount }} x {{ ingredient.item.name }}[/*]
|
||||
{% else %}
|
||||
{% if ingredient.amount > 1 %}
|
||||
[*][b]{{ ingredient.amount }} x [/b]{{ ingredient.item.name }}[/*]
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
[/LIST]
|
||||
[/td]
|
||||
{% endwith %}
|
||||
[/tr]
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
[/table]
|
||||
</code>
|
||||
{% endblock context %}
|
133
dj/scon/templates/scon/crafting/forum_efefay.html
Normal file
133
dj/scon/templates/scon/crafting/forum_efefay.html
Normal file
@ -0,0 +1,133 @@
|
||||
{% extends "scon/base.html" %}
|
||||
|
||||
{% block css %}
|
||||
{{ block.super }}
|
||||
|
||||
<style>
|
||||
<!--
|
||||
.parents-0 {
|
||||
color: #595959;
|
||||
}
|
||||
|
||||
.parents-1 {
|
||||
color: #00b050;
|
||||
}
|
||||
|
||||
.parents-2 {
|
||||
color: #1f497d;
|
||||
}
|
||||
|
||||
.parents-3 {
|
||||
color: #7030a0;
|
||||
}
|
||||
|
||||
.parents-4 {
|
||||
color: #e46c0a;
|
||||
}
|
||||
|
||||
.parents-5 {
|
||||
color: #ff3399;
|
||||
}
|
||||
-->
|
||||
</style>
|
||||
|
||||
{% endblock css %}
|
||||
|
||||
{% block context %}
|
||||
|
||||
<h1>Forum</h1>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>What ya wanna</th>
|
||||
<th>What ya needze</th>
|
||||
</tr>
|
||||
{% for ore in ores %}
|
||||
<tr>
|
||||
<td>{{ ore.name }}</td>
|
||||
<td>N/A{% if ore.typ == 13 %} (This is a component you cannot craft){% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for item in items %}
|
||||
|
||||
{% if item.primary_recipee %}
|
||||
<tr>
|
||||
{% with item.primary_recipee as recipee %}
|
||||
<td>
|
||||
{{ recipee.output.name }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<ul>
|
||||
{% for ingredient in recipee.ingredients %}
|
||||
<li class="parents-{{ ingredient.item.parents|length }}">
|
||||
{% if ingredient.item != item %}
|
||||
{{ ingredient.amount }} x {{ ingredient.item.name }}
|
||||
{% else %}
|
||||
{% if ingredient.amount > 1 %}
|
||||
<b><i>{{ ingredient.amount }}</i> x {{ ingredient.item.name }}</b>
|
||||
{% else %}
|
||||
<b>{{ ingredient.amount }} x {{ ingredient.item.name }}</b>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
{% endwith %}
|
||||
</tr>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<code>
|
||||
[table]
|
||||
[tr][th][b][font=arial, sans-serif][size=12]Crafting Result [/size][/font][/b]
|
||||
[b][font=arial, sans-serif][size=12](the components you want)[/size][/font][/b][/th][th][b][font=arial, sans-serif][size=12]Prerequisite Materials [/size][/font][/b]
|
||||
[b][font=arial, sans-serif][size=12](what you need to get the result)[/size][/font][/b][/th][/tr]
|
||||
{% for ore in ores %}
|
||||
[tr]
|
||||
[td][color=#595959]{{ ore.name }}[/color][/td]
|
||||
[td]N/A{% if ore.typ == 13 %} (This is a component you cannot craft){% endif %}[/td]
|
||||
[/tr]
|
||||
{% endfor %}
|
||||
{% for item in items %}
|
||||
{% if item.primary_recipee %}
|
||||
[tr]
|
||||
{% with item.primary_recipee as recipee %}
|
||||
[td]
|
||||
{% with recipee.output.parents|length as depth %}
|
||||
[color={% if depth == 0 %}#595959{% elif depth == 1 %}#00b050{% elif depth == 2 %}#1f497d{% else %}#7030a0{% endif %}]{{ recipee.output.name }}[/color]
|
||||
{% endwith %}
|
||||
[/td]
|
||||
|
||||
|
||||
[td]
|
||||
[LIST]
|
||||
{% for ingredient in recipee.ingredients %}
|
||||
[*]{% with ingredient.item.parents|length as depth %}
|
||||
[font=arial, sans-serif][size=12]
|
||||
{% if ingredient.item != item %}
|
||||
{{ ingredient.amount }} x [color={% if depth == 0 %}#595959{% elif depth == 1 %}#00b050{% elif depth == 2 %}#1f497d{% else %}#7030a0{% endif %}]{{ ingredient.item.name }}[/color]
|
||||
{% else %}
|
||||
{% if ingredient.amount > 1 %}
|
||||
[b][i]{{ ingredient.amount }}[/i] x [color={% if depth == 0 %}#595959{% elif depth == 1 %}#00b050{% elif depth == 2 %}#1f497d{% else %}#7030a0{% endif %}]{{ ingredient.item.name }}[/color][/b]
|
||||
{% else %}
|
||||
[b]{{ ingredient.amount }} x [color={% if depth == 0 %}#595959{% elif depth == 1 %}#00b050{% elif depth == 2 %}#1f497d{% else %}#7030a0{% endif %}]{{ ingredient.item.name }}[/color][/b]
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endwith %}[/size][/font][/*]
|
||||
{% endfor %}
|
||||
[/LIST]
|
||||
[/td]
|
||||
|
||||
{% endwith %}
|
||||
[/tr]
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
[/table]
|
||||
</code>
|
||||
{% endblock context %}
|
@ -16,4 +16,17 @@ def crafting(request):
|
||||
tree = None
|
||||
c = RequestContext(request, {'tree': tree,
|
||||
'items': items})
|
||||
return HttpResponse(t.render(c))
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
def crafting_forum(request):
|
||||
t = loader.get_template('scon/crafting/forum_efefay.html')
|
||||
items = models.Item.objects.filter(craftable=True)
|
||||
ores = []
|
||||
for item in items.filter(typ__in=[12, 13]):
|
||||
if len(item.parents()) == 0 and item.primary_recipee():
|
||||
ores.append(item)
|
||||
tree = None
|
||||
c = RequestContext(request, {'tree': tree,
|
||||
'ores': ores,
|
||||
'items': items})
|
||||
return HttpResponse(t.render(c))
|
||||
|
@ -8,7 +8,9 @@ urlpatterns = patterns('',
|
||||
# url(r'^$', 'dj.views.home', name='home'),
|
||||
# url(r'^blog/', include('blog.urls')),
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^crafting/', 'dj.scon.views.crafting', name='scon_crafting'),
|
||||
url(r'^crafting/forum/$', 'dj.scon.views.crafting_forum', name='scon_crafting_forum'),
|
||||
url(r'^crafting/$', 'dj.scon.views.crafting', name='scon_crafting'),
|
||||
|
||||
)
|
||||
|
||||
if settings.DEBUG or getattr(settings, 'SERVE_INTERNAL', False):
|
||||
|
@ -77,7 +77,7 @@ class Browser(QtGui.QMainWindow):
|
||||
self.connect(self.bt_back, QtCore.SIGNAL("clicked()"), self.html.back)
|
||||
self.connect(self.bt_ahead, QtCore.SIGNAL("clicked()"), self.html.forward)
|
||||
|
||||
self.tb_url.setText('Search...')
|
||||
self.tb_url.setText('/crafting/forum')
|
||||
|
||||
self.browse()
|
||||
|
||||
@ -87,10 +87,13 @@ class Browser(QtGui.QMainWindow):
|
||||
Webview widget.
|
||||
"""
|
||||
|
||||
#url = self.tb_url.text() if self.tb_url.text() else self.default_url
|
||||
#self.html.load(QtCore.QUrl(url))
|
||||
url = self.tb_url.text() if self.tb_url.text() else 'page:///'
|
||||
if not str(url).startswith('page://'):
|
||||
url = 'page://' + url
|
||||
self.html.load(QtCore.QUrl(url))
|
||||
#self.html.setHtml(self.serve())
|
||||
self.html.load(QtCore.QUrl('page:///crafting/overview/'))
|
||||
|
||||
#self.html.load(QtCore.QUrl('page:///crafting/forum/'))
|
||||
self.html.show()
|
||||
|
||||
def serve(self, what=None):
|
||||
|
@ -1,13 +1,14 @@
|
||||
"""
|
||||
Library dedicated to Star Conflict Logs.
|
||||
|
||||
Development plan:
|
||||
- Make Combat Log parse completely.
|
||||
- Make Game Log parse to get information like the local nickname or other needed infos.
|
||||
- Create a soft emulation, which keeps track of the basic game outcome / events.
|
||||
|
||||
Additional Goals:
|
||||
- probably save games in own format to keep space.
|
||||
- database entries for kills, encountered players, etc.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Library dedicated to Star Conflict Logs.
|
||||
|
||||
Development plan:
|
||||
- Make Combat Log parse completely.
|
||||
- Make Game Log parse to get information like the local nickname or other needed infos.
|
||||
- Create a soft emulation, which keeps track of the basic game outcome / events.
|
||||
|
||||
Additional Goals:
|
||||
- probably save games in own format to keep space.
|
||||
- database entries for kills, encountered players, etc.
|
||||
|
||||
"""
|
@ -1,9 +1,16 @@
|
||||
|
||||
L_CMBT = 'CMBT'
|
||||
L_WARNING = 'WARNING'
|
||||
L_NET = 'NET'
|
||||
L_CHAT = 'CHAT'
|
||||
|
||||
class Log(object):
|
||||
matcher = None
|
||||
trash = False
|
||||
|
||||
@classmethod
|
||||
def is_handler(cls, log):
|
||||
return False
|
||||
|
||||
|
||||
def unpack(self):
|
||||
pass
|
||||
|
@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
@ -1,3 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
todo:
|
||||
- English implementation first.
|
||||
@ -19,9 +21,10 @@
|
||||
The typical log entry
|
||||
"""
|
||||
import re
|
||||
from base import Log
|
||||
from base import Log, L_CMBT
|
||||
|
||||
class CombatLog(Log):
|
||||
__slots__ = ['matcher', 'trash', '_match_id', 'values']
|
||||
@classmethod
|
||||
def _log_handler(cls, log):
|
||||
if log.get('log', '').strip().startswith(cls.__name__):
|
||||
@ -30,7 +33,7 @@ class CombatLog(Log):
|
||||
|
||||
@classmethod
|
||||
def is_handler(cls, log):
|
||||
if log.get('logtype', None) == 'CMBT':
|
||||
if log.get('logtype', None) == L_CMBT:
|
||||
return cls._log_handler(log)
|
||||
return False
|
||||
|
||||
@ -38,22 +41,28 @@ class CombatLog(Log):
|
||||
self.values = values
|
||||
|
||||
def unpack(self):
|
||||
self._match_id = None
|
||||
# unpacks the data from the values.
|
||||
if hasattr(self, 'matcher') and self.matcher:
|
||||
matchers = self.matcher
|
||||
if not isinstance(matchers, list):
|
||||
matchers = [matchers,]
|
||||
for matcher in matchers:
|
||||
for i, matcher in enumerate(matchers):
|
||||
m = matcher.match(self.values.get('log', ''))
|
||||
if m:
|
||||
self.values.update(m.groupdict())
|
||||
self._match_id = i
|
||||
return True
|
||||
# unknown?
|
||||
self.trash = True
|
||||
|
||||
# @todo: where does this come from?
|
||||
class Action(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
pass
|
||||
|
||||
class Gameplay(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = [
|
||||
# usual: team(reason). explained reason.
|
||||
re.compile(r"^Gameplay\sfinished\.\sWinner\steam\:\s+(?P<winner_team>\d+)\((?P<winner_reason>\w+)\)\.\sFinish\sreason\:\s'(?P<reason_verbose>[^']+)'\.\sActual\sgame\stime\s+(?P<game_time>\d+|\d+\.\d+)\ssec"),
|
||||
@ -62,27 +71,35 @@ class Gameplay(CombatLog):
|
||||
]
|
||||
|
||||
class Apply(CombatLog): # Apply Aura.
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^Apply\saura\s'(?P<aura_name>\w+)'\sid\s(?P<id>\d+)\stype\s(?P<aura_type>\w+)\sto\s'(?P<target_name>[^\']+)'")
|
||||
|
||||
class Damage(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^Damage\s+(?P<source_name>[^\s]+)\s\->\s+(?P<target_name>[^\s]+)\s+(?P<amount>(?:\d+|\d+\.\d+))(?:\s(?P<module_class>[^\s]+)\s|\s{2,2})(?P<flags>(?:\w|\|)+)")
|
||||
|
||||
class Spawn(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^Spawn\sSpaceShip\sfor\splayer(?P<player>\d+)\s\((?P<name>[^,]+),\s+(?P<hash>#\w+)\)\.\s+'(?P<ship_class>\w+)'")
|
||||
|
||||
class Spell(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^Spell\s'(?P<spell_name>\w+)'\sby\s+(?P<source_name>.*)(?:\((?P<module_name>\w+)\)|)\stargets\((?P<target_num>\d+)\)\:(?:$|\s(?P<targets>.+))")
|
||||
|
||||
class Reward(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^Reward\s+(?P<name>[^\s]+)(?:\s(?P<ship_class>\w+)\s+|\s+)(?P<amount>\d+)\s(?P<reward_type>.*)\s+for\s(?P<reward_reason>.*)")
|
||||
|
||||
class Participant(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^\s+Participant\s+(?P<source_name>[^\s]+)(?:\s{2}(?P<ship_class>\w+)|\s{30,})\s+(?:totalDamage\s(?P<total_damage>(?:\d+|\d+\.\d+));\smostDamageWith\s'(?P<module_class>[^']+)';(?P<additional>.*)|<(?P<other>\w+)>)")
|
||||
|
||||
class Rocket(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^Rocket\s(?P<event>launch|detonation)\.\sowner\s'(?P<name>[^']+)'(?:,\s(?:def\s'(?P<missile_type>\w+)'|target\s'(?P<target>[^']+)'|reason\s'(?P<reason>\w+)'|directHit\s'(?P<direct_hit>[^']+)'))+")
|
||||
|
||||
class Heal(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = [
|
||||
# heal by module
|
||||
re.compile(r"^Heal\s+(?P<source_name>[^\s]+)\s\->\s+(?P<target_name>[^\s]+)\s+(?P<amount>(?:\d+|\d+\.\d+))\s(?P<module_class>[^\s]+)"),
|
||||
@ -91,6 +108,7 @@ class Heal(CombatLog):
|
||||
]
|
||||
|
||||
class Killed(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = [
|
||||
re.compile(r"^Killed\s(?P<target_name>[^\s]+)\s+(?P<ship_class>\w+);\s+killer\s(?P<source_name>[^\s]+)\s*"),
|
||||
re.compile(r"^Killed\s(?P<object>[^\(]+)\((?P<target_name>\w+)\);\s+killer\s(?P<source_name>[^\s]+)\s*"),
|
||||
@ -98,19 +116,24 @@ class Killed(CombatLog):
|
||||
]
|
||||
|
||||
class Captured(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^Captured\s'(?P<objective>[^']+)'\(team\s(?P<team>\d+)\)\.(?:\sAttackers\:(?P<attackers>.*)|.*)")
|
||||
|
||||
class AddStack(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^AddStack\saura\s'(?P<spell_name>\w+)'\sid\s(?P<id>\d+)\stype\s(?P<type>\w+)\.\snew\sstacks\scount\s(?P<stack_count>\d+)")
|
||||
|
||||
class Cancel(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^Cancel\saura\s'(?P<spell_name>\w+)'\sid\s(?P<id>\d+)\stype\s(?P<type>\w+)\sfrom\s'(?P<source_name>[^']+)'")
|
||||
|
||||
class Scores(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = re.compile(r"^Scores\s+-\sTeam1\((?P<team1_score>(?:\d+|\d+\.\d+))\)\sTeam2\((?P<team2_score>(?:\d+|\d+\.\d+))\)")
|
||||
|
||||
# Special classes
|
||||
class GameEvent(CombatLog):
|
||||
__slots__ = CombatLog.__slots__
|
||||
matcher = [
|
||||
# game session identifier.
|
||||
re.compile(r"^Connect\sto\sgame\ssession\s+(?P<game_session>\d+)"),
|
||||
@ -127,20 +150,25 @@ class GameEvent(CombatLog):
|
||||
return False
|
||||
|
||||
def unpack(self):
|
||||
self._match_id = None
|
||||
# unpacks the data from the values.
|
||||
# small override to remove trailing "="s in the matching.
|
||||
if hasattr(self, 'matcher') and self.matcher:
|
||||
matchers = self.matcher
|
||||
if not isinstance(matchers, list):
|
||||
matchers = [matchers,]
|
||||
for matcher in matchers:
|
||||
for i, matcher in enumerate(matchers):
|
||||
m = matcher.match(self.values.get('log', '').strip('=').strip())
|
||||
if m:
|
||||
self.values.update(m.groupdict())
|
||||
self._match_id = i
|
||||
return True
|
||||
# unknown?
|
||||
self.trash = True
|
||||
|
||||
class UserEvent(CombatLog):
|
||||
""" special class for combat logs that might be associated with the playing player """
|
||||
__slots__ = CombatLog.__slots__
|
||||
@classmethod
|
||||
def _log_handler(cls, log):
|
||||
if log.get('log', '').strip():
|
||||
|
170
logs/game.py
170
logs/game.py
@ -1,4 +1,172 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from logs.base import Log, L_WARNING
|
||||
import re
|
||||
"""
|
||||
Interesting Lines:
|
||||
|
||||
23:16:27.427 | Steam initialized appId 212070, userSteamID 1|1|4c5a01, userName 'G4bOrg'
|
||||
23:16:36.214 | ====== starting level: 'levels/mainmenu/mainmenu' ======
|
||||
23:16:38.822 | ====== level started: 'levels/mainmenu/mainmenu' success ======
|
||||
23:16:44.251 | ====== starting level: 'levels\mainmenu\mm_empire' ======
|
||||
23:16:46.464 | ====== level started: 'levels\mainmenu\mm_empire' success ======
|
||||
|
||||
--- Date: 2014-07-18 (Fri Jul 2014) Mitteleuropäische Sommerzeit UTC+01:00
|
||||
|
||||
23:55:55.517 | MasterServerSession: connect to dedicated server, session 6777304, at addr 159.253.138.162|35005
|
||||
23:55:55.543 | client: start connecting to 159.253.138.162|35005...
|
||||
23:55:55.683 | client: connected to 159.253.138.162|35005, setting up session...
|
||||
23:55:55.886 | client: ADD_PLAYER 0 (OregyenDuero [OWL], 00039C86) status 6 team 1 group 1178422
|
||||
23:55:55.886 | client: ADD_PLAYER 1 (R0gue, 0012768A) status 6 team 2 group 1178451
|
||||
23:55:55.886 | client: ADD_PLAYER 2 (g4borg [OWL], 0003A848) status 1 team 1 group 1178422
|
||||
23:55:55.886 | client: ADD_PLAYER 3 (WladTepes, 001210D8) status 6 team 1
|
||||
23:55:55.886 | client: ADD_PLAYER 4 (oberus [], 000FE9B2) status 6 team 2
|
||||
23:55:55.886 | client: ADD_PLAYER 5 (TheGuns58, 00121C58) status 6 team 1
|
||||
23:55:55.886 | client: ADD_PLAYER 6 (Belleraphon, 0004C744) status 2 team 2
|
||||
23:55:55.886 | client: ADD_PLAYER 7 (TopoL, 00007E1F) status 6 team 1
|
||||
23:55:55.886 | client: ADD_PLAYER 8 (unicoimbraPT, 000C4FAC) status 6 team 2
|
||||
23:55:55.886 | client: ADD_PLAYER 9 (AeroBobik [], 00082047) status 6 team 1
|
||||
23:55:55.886 | client: ADD_PLAYER 10 (Samson4321 [], 000B93AF) status 6 team 2
|
||||
23:55:55.886 | client: ADD_PLAYER 11 (nol [], 00069165) status 6 team 1
|
||||
23:55:55.886 | client: ADD_PLAYER 12 (Pudwoppa, 000334A4) status 2 team 2
|
||||
23:55:55.886 | client: ADD_PLAYER 13 (IgorMad [], 000D2AF3) status 6 team 1
|
||||
23:55:55.886 | client: ADD_PLAYER 14 (YokaI, 000F1CC9) status 6 team 2
|
||||
23:55:55.886 | client: ADD_PLAYER 15 (MrAnyKey [], 0012246C) status 6 team 2 group 1178451
|
||||
23:55:55.886 | client: ADD_PLAYER 30 ((bot)David, 00000000) status 4 team 1
|
||||
23:55:55.886 | client: ADD_PLAYER 31 ((bot)George, 00000000) status 4 team 2
|
||||
23:55:55.886 | client: server assigned id 2
|
||||
23:55:55.886 | client: got level load message 's1340_thar_aliendebris13'
|
||||
23:55:55.889 | reset d3d device
|
||||
23:55:56.487 | ReplayManager: stopping activity due to map change
|
||||
23:55:56.576 | ====== starting level: 'levels\area2\s1340_thar_aliendebris13' KingOfTheHill client ======
|
||||
|
||||
|
||||
"""
|
||||
|
||||
class GameLog(Log):
|
||||
__slots__ = ['matcher', 'trash', '_match_id', 'values']
|
||||
@classmethod
|
||||
def is_handler(cls, log):
|
||||
if log.get('logtype', None) == '': # we handle only logs with empty logtype.
|
||||
return cls._is_handler(log)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def _is_handler(cls, log):
|
||||
return False
|
||||
|
||||
def __init__(self, values=None):
|
||||
self.values = values
|
||||
|
||||
def unpack(self):
|
||||
self._match_id = None
|
||||
# unpacks the data from the values.
|
||||
if hasattr(self, 'matcher') and self.matcher:
|
||||
matchers = self.matcher
|
||||
if not isinstance(matchers, list):
|
||||
matchers = [matchers,]
|
||||
for i, matcher in enumerate(matchers):
|
||||
m = matcher.match(self.values.get('log', ''))
|
||||
if m:
|
||||
self.values.update(m.groupdict())
|
||||
self._match_id = i
|
||||
return True
|
||||
# unknown?
|
||||
self.trash = True
|
||||
|
||||
class WarningLog(Log):
|
||||
__slots__ = ['trash',]
|
||||
trash = True
|
||||
|
||||
@classmethod
|
||||
def is_handler(cls, log):
|
||||
if log.get('logtype', None) == L_WARNING:
|
||||
return True
|
||||
return False
|
||||
|
||||
def __init__(self, values=None):
|
||||
pass
|
||||
|
||||
########################################################################################################
|
||||
# Individual logs.
|
||||
|
||||
class SteamInitialization(GameLog):
|
||||
matcher = []
|
||||
|
||||
class MasterServerSession(GameLog):
|
||||
matcher = [
|
||||
re.compile(r"^MasterServerSession\:\sconnect\sto\sdedicated\sserver(?:,\s|session\s(?P<session_id>\d+)|at addr (?P<addr>\d+\.\d+\.\d+\.\d+)\|(?P<port>\d+))+"),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def _is_handler(cls, log):
|
||||
if log.get('log', '').startswith('MasterServerSession'):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class ClientInfo(GameLog):
|
||||
# Note: clinfo holds the subtype of this packet.
|
||||
matcher = [
|
||||
# connecting; addr, port
|
||||
re.compile(r"^client\:\sstart\s(?P<clinfo>connecting)\sto\s(?P<addr>\d+\.\d+\.\d+\.\d+)\|(?P<port>\d+)\.\.\."),
|
||||
# connected; addr, port
|
||||
re.compile(r"^client\:\s(?P<clinfo>connected)\sto\s(?P<addr>\d+\.\d+\.\d+\.\d+)\|(?P<port>\d+).*"),
|
||||
# ADD_PLAYER; pnr, player, clantag, player_id, status, team, group
|
||||
re.compile(r"^client\:\s(?P<clinfo>ADD_PLAYER)\s+(?P<pnr>\d+)\s+\((?P<player>[^\s\,]+)(?:\s\[(?P<clantag>\w+)\],|\s\[\],|,)\s(?P<player_id>\w+)\)(?:\s|status\s(?P<status>\d+)|team\s(?P<team>\d+)|group\s(?P<group>\d+))+"),
|
||||
# assigned; myid
|
||||
re.compile(r"^client\:\sserver\s(?P<clinfo>assigned)\sid\s(?P<myid>\d+)"),
|
||||
# level; level
|
||||
re.compile(r"^client\:\sgot\s(?P<clinfo>level)\sload\smessage\s'(?P<level>[^']+)'"),
|
||||
# leave; pnr
|
||||
re.compile(r"^client\:\splayer\s(?P<pnr>\d+)\s(?P<clinfo>leave)\sgame"),
|
||||
# avgPing; avg_ping, avg_packet_loss, avg_snapshot_loss
|
||||
re.compile(r"^client\:\s(?P<clinfo>avgPing)\s(?P<avg_ping>[^;]+)(?:\;|\s|avgPacketLoss\s(?P<avg_packet_loss>[^;]+)|avgSnapshotLoss\s(?P<avg_snapshot_loss>[^;$]+))+"),
|
||||
# closed; dr
|
||||
re.compile(r"^client\:\sconnection\s(?P<clinfo>closed)\.(?:\s|(?P<dr>.*))+"),
|
||||
# disconnect; addr, port, dr
|
||||
re.compile(r"^client\:\s(?P<clinfo>disconnect)\sfrom\sserver\s(?P<addr>\d+\.\d+\.\d+\.\d+)\|(?P<port>\d+)\.(?:\s|(?P<dr>\w+))+"),
|
||||
# ready;
|
||||
re.compile(r"^client\:\ssend\s(?P<clinfo>ready)\smessage"),
|
||||
# init; ping
|
||||
re.compile(r"^client\:\sgot\s(?P<clinfo>init)\smessage\s+\(and\s1st\ssnapshot\)\.\sping\s(?P<ping>\d+)"),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def _is_handler(cls, log):
|
||||
if log.get('log', '').startswith('client:'):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class StartingLevel(GameLog):
|
||||
# level, gametype, unknown_gametype
|
||||
matcher = [
|
||||
re.compile(r"^======\sstarting\slevel\:\s'(?P<level>[^']+)'(?:\s|client|(?P<gametype>KingOfTheHill)|(?P<unknown_gametype>[^\s]+))+======"),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def _is_handler(cls, log):
|
||||
if log.get('log', '').startswith('====== starting'):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class LevelStarted(GameLog):
|
||||
matcher = []
|
||||
|
||||
@classmethod
|
||||
def _is_handler(cls, log):
|
||||
if log.get('log', '').startswith('====== level'):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
GAME_LOGS = []
|
||||
GAME_LOGS = [#SteamInitialization,
|
||||
MasterServerSession,
|
||||
ClientInfo,
|
||||
StartingLevel,
|
||||
#LevelStarted,
|
||||
]
|
@ -1,4 +1,5 @@
|
||||
#
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Author: Gabor Guzmics, 2013-2014
|
||||
|
||||
@ -30,6 +31,9 @@ class LogFile(object):
|
||||
def set_data(self, data):
|
||||
self._data = data
|
||||
|
||||
def _unset_data(self):
|
||||
self._data = None
|
||||
|
||||
def parse(self):
|
||||
# parse _data if we still have no lines.
|
||||
if self._data:
|
||||
|
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Resolves Logs.
|
||||
"""
|
||||
|
133
logs/session.py
133
logs/session.py
@ -9,6 +9,7 @@ class LogSession(object):
|
||||
The Log-Session is supposed to save one directory of logs.
|
||||
It can parse its logs, and build up its internal structure into Battle Instances etc.
|
||||
"""
|
||||
VALID_FILES = ['combat.log', 'game.log', ] # extend this to other logs.
|
||||
|
||||
def __init__(self, directory):
|
||||
''' if directory is a file, it will be handled as a compressed folder '''
|
||||
@ -22,22 +23,47 @@ class LogSession(object):
|
||||
# self.net_log = None
|
||||
|
||||
self.directory = directory
|
||||
self._zip_source = False
|
||||
self._zip_source = None
|
||||
self.idstr = None # id string to identify this log instance.
|
||||
self._error = False
|
||||
|
||||
def parse_files(self):
|
||||
''' parses the logfiles '''
|
||||
# check if directory is a file
|
||||
def validate(self, contents=False):
|
||||
"""
|
||||
- validates if the logfiles are within this package.
|
||||
- sets the idstr of this object.
|
||||
@todo: in-depth validation of logs, on contents=True.
|
||||
"""
|
||||
self._zip_source = os.path.isfile(self.directory) or False
|
||||
v = False
|
||||
try:
|
||||
if self._zip_source:
|
||||
v = self._unzip_validate()
|
||||
if v > 0:
|
||||
self.idstr = os.path.split(self.directory)[1].replace('.zip', '').lower()
|
||||
else:
|
||||
v = self._validate_files_exist()
|
||||
if v > 0:
|
||||
self.idstr = os.path.split(self.directory)[1].lower()
|
||||
except:
|
||||
return False
|
||||
return v
|
||||
|
||||
def parse_files(self, files=None):
|
||||
''' parses the logfiles '''
|
||||
# perform simple validation.
|
||||
if self._zip_source is None:
|
||||
self.validate(False)
|
||||
if self._zip_source:
|
||||
self._unzip_logs()
|
||||
self._unzip_logs(files)
|
||||
else:
|
||||
self.combat_log = CombatLogFile(os.path.join(self.directory, 'combat.log'))
|
||||
self.combat_log.read()
|
||||
self.game_log = GameLogFile(os.path.join(self.directory, 'game.log'))
|
||||
self.game_log.read()
|
||||
# parse all files
|
||||
self.combat_log.parse()
|
||||
self.game_log.parse()
|
||||
if 'combat.log' in files:
|
||||
self.combat_log = CombatLogFile(os.path.join(self.directory, 'combat.log'))
|
||||
self.combat_log.read()
|
||||
self.combat_log.parse()
|
||||
if 'game.log' in files:
|
||||
self.game_log = GameLogFile(os.path.join(self.directory, 'game.log'))
|
||||
self.game_log.read()
|
||||
self.game_log.parse()
|
||||
|
||||
def determine_owner(self):
|
||||
''' determines the user in the parsed gamelog '''
|
||||
@ -47,19 +73,79 @@ class LogSession(object):
|
||||
''' parses the battles '''
|
||||
pass
|
||||
|
||||
def _unzip_logs(self):
|
||||
def _unzip_logs(self, files=None):
|
||||
z = zipfile.ZipFile(self.directory, "r")
|
||||
try:
|
||||
for filename in z.namelist():
|
||||
fn = os.path.split(filename)[1] or ''
|
||||
fn = fn.lower()
|
||||
if fn:
|
||||
if fn == 'combat.log' and (not files or fn in files):
|
||||
self.combat_log = CombatLogFile(fn)
|
||||
self.combat_log.set_data(z.read(filename))
|
||||
elif fn == 'game.log' and (not files or fn in files):
|
||||
self.game_log = GameLogFile(fn)
|
||||
self.game_log.set_data(z.read(filename))
|
||||
except:
|
||||
self._error = True
|
||||
return
|
||||
finally:
|
||||
z.close()
|
||||
|
||||
def _unzip_validate(self):
|
||||
z = zipfile.ZipFile(self.directory, "r")
|
||||
found = 0
|
||||
for filename in z.namelist():
|
||||
fn = os.path.split(filename)[1] or ''
|
||||
fn = fn.lower()
|
||||
if fn:
|
||||
if fn == 'combat.log':
|
||||
self.combat_log = CombatLogFile(fn)
|
||||
self.combat_log.set_data(z.read(filename))
|
||||
elif fn == 'game.log':
|
||||
self.game_log = GameLogFile(fn)
|
||||
self.game_log.set_data(z.read(filename))
|
||||
|
||||
if fn and fn in self.VALID_FILES:
|
||||
found += 1
|
||||
z.close()
|
||||
return found
|
||||
|
||||
def _validate_files_exist(self):
|
||||
found = 0
|
||||
for f in self.VALID_FILES:
|
||||
if os.path.exists(os.path.join(self.directory, f)):
|
||||
found += 1
|
||||
return found
|
||||
|
||||
class LogSessionCollector(object):
|
||||
def __init__(self, directory):
|
||||
self.initial_directory = directory
|
||||
self.sessions = []
|
||||
self.find_sessions()
|
||||
|
||||
def find_sessions(self):
|
||||
for f in os.listdir(self.initial_directory):
|
||||
full_dir = os.path.join(self.initial_directory, f)
|
||||
if os.path.isdir(full_dir) or full_dir.lower().endswith('.zip'):
|
||||
self.sessions.append(LogSession(full_dir))
|
||||
|
||||
def collect(self):
|
||||
sessions = []
|
||||
for session in self.sessions:
|
||||
try:
|
||||
if session.validate():
|
||||
sessions.append(session)
|
||||
except:
|
||||
continue
|
||||
return sessions
|
||||
|
||||
def collect_unique(self):
|
||||
''' collects all sessions into a dictionary ordered by their idstr.
|
||||
sessions without idstr, or already existing (first served) are omitted
|
||||
parsing is not done.
|
||||
'''
|
||||
# note this function resets sessions to the working ones.
|
||||
self.sessions = self.collect()
|
||||
sessions_dict = {}
|
||||
for session in self.sessions:
|
||||
if session.idstr and not session.idstr in sessions_dict.keys():
|
||||
sessions_dict[session.idstr] = session
|
||||
return sessions_dict
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
@ -67,4 +153,7 @@ if __name__ == '__main__':
|
||||
l_zip = LogSession('D:\\Users\\g4b\\Documents\\My Games\\sc\\2014.05.20 23.49.19.zip')
|
||||
|
||||
l_zip.parse_files()
|
||||
print l_zip.combat_log.lines
|
||||
print l_zip.combat_log.lines
|
||||
|
||||
collector = LogSessionCollector('D:\\Users\\g4b\\Documents\\My Games\\sc\\')
|
||||
print collector.collect_unique()
|
Loading…
Reference in New Issue
Block a user