REBOL [ Title: "Half-life log parser" Author: "Cal Dixon" Date: 4-Mar-2004 File: %hllogparser.r Purpose: "Allows a rebol script to parse server logs from the game: Half-life" Library: [ level: 'intermediate platform: 'all type: [tool game function] domain: [game text-processing parse] tested-under: none support: none license: 'PD see-also: %rcon.r ] ] logparser-ctx: context [ prefix: [ "L " copy tdate date " - " copy ttime time ": " ] comment: [ "//" thru "^/" ] tdate: copy "" ttime: copy "" tstring: copy "" tuser: copy "" tvictim: copy "" tvalue: copy "" tusername: copy "" tuid: copy "" twonid: copy "" tteamid: copy "" tprop: copy "" tevent: copy [] tlog: copy [] month: [ digit digit ] day: [ digit digit ] year: [ digit digit digit digit ] date: [ month "/" day "/" year ] time: [ hour ":" minute ":" second ] minute: [ digit digit ] second: [ digit digit ] hour: [ digit digit ] digit: charset "0123456789" nonquote: complement charset {"} nonqb: complement charset {"<>} nonlf: complement charset {^/} propchar: complement charset " )" string: [ copy tstring any nonquote ] value: [ copy tvalue any nonquote ] username: [ some nonqb ] uid: [ "<" copy tuid [ some digit | "BOT" ] ">" ] wonid: [ "<" copy twonid some nonqb ">" ] teamid: [ "<" copy tteamid any nonqb ">" ] user: [ opt {"} copy tusername username uid wonid teamid opt {"} (tuser: reduce [tusername tuid twonid tteamid]) ] victim: [ opt {"} copy tusername username uid wonid teamid opt {"} (tvictim: reduce [tusername tuid twonid tteamid]) ] forgiver: [ {"} some nonquote {" (WON ID : } some digit ")" ] forgiven: [ {"} some nonquote {" (WON ID : } some digit ")" ] propvalue: [ any nonquote ] property: [ copy tprop [some propchar opt [{ "} propvalue {"}]] ] logstart: [ "Log file started " thru "^/" ] loadmap: [ {Loading map "} string {"^/} ] cvar: [ {Server cvar "} string {" = "} value {"^/} ] startmap: [ {Started map "} string {" (CRC "} value {")^/} ] fileload: [ {"} string {" loaded^/} ] joingame: [ user " entered the game^/" ] jointeam: [ user { joined team "} string {"^/} ] changeteam: [ user { changed to team "} string {"^/} ] selectweapon: [ user { selected weapon "} string {"^/} ] acquireweapon: [ user { acquired weapon "} string {"^/} ] say: [ user { say "} copy tstring to {"^/} {"^/} ] connected: [ user { connected, address "} string {"^/} ] attack: [ user " attacked " victim { with "} string {" (} property {)^/} ] landhard: [ user " landed...... hard^/" ] kill: [ user " killed " victim { with "} string {"^/} ] killself: [ user " killed self^/" ] worldkill: [ user " killed by world^/" ] tk: [ "**TeamKill by " user "^/"] disconnect: [ user " disconnected^/" ] forgivetk: [ forgiven "^/ was forgiven by ^/" forgiver " ^/" ] rcon: [ {Rcon: "} rconcommand {" from "} string {"^/}] badrcon: [ {Bad Rcon: "} rconcommand {" from "} string {"^/}] rconcommand: [ realrconcommand | any nonquote ] realrconcommand: [ "rcon " sessionid { "} password {" } realcommand ] sessionid: [ some digit ] password: [ any nonquote ] realcommand: [ any nonquote ] namechange: [ user { changed name to "} string {"^/} ] worldaction: [ {World triggered "} string {"^/} ] pmsg: [ user " tell " victim { "} string to {"^/} {"^/} ] serversay: [ {Server say "} string to {"^/} {"^/} ] metamodline: [ "[META] " copy tstring to "^/" "^/" ] adminmodline: [ "[ADMIN] " copy tstring to "^/" "^/" ] steamok: [ user { STEAM USERID validated^/} ] kick: [ "Kick: " user { was kicked by "} string {"^/} ] event: [ logstart (insert tevent reduce [none 'LOGSTART none none]) | loadmap (insert tevent reduce [none 'LOADMAP none tstring]) | connected (insert tevent reduce [tuser 'CONNECTED none tstring]) | steamok (insert tevent reduce [tuser 'STEAMOK none none]) | "Server cvars start^/" | cvar | "Server cvars end^/" | startmap (insert tevent reduce [none 'STARTMAP none tstring]) | fileload | joingame (insert tevent reduce [tuser 'JOINGAME none none]) | jointeam (insert tevent reduce [tuser 'JOINTEAM none tstring]) | selectweapon (insert tevent reduce [tuser 'SELECTWEAPON none tstring]) | acquireweapon (insert tevent reduce [tuser 'ACQUIREWEAPON none tstring]) | say (insert tevent reduce [tuser 'SAY none tstring]) | attack (insert tevent reduce [tuser 'ATTACK tvictim reduce [tstring tprop]]) | landhard (insert tevent reduce [tuser 'LANDHARD none none]) | killself (insert tevent reduce [tuser 'KILLSELF none none]) | kill (insert tevent reduce [tuser 'KILL tvictim tstring]) | worldkill (insert tevent reduce [tuser 'WORLDKILL none none]) | tk (insert tevent reduce [tuser 'TEAMKILL none none]) | kick (insert tevent reduce [tuser 'KICKED none none]) | disconnect (insert tevent reduce [tuser 'DISCONNECT none none]) | forgivetk | rcon | badrcon | namechange (insert tevent reduce [tuser 'NAMECHANGE none tstring]) | worldaction (insert tevent reduce [none 'WORLDEVENT none tstring]) | pmsg (insert tevent reduce [tuser 'PRIVATEMSG tvictim tstring]) | serversay (insert tevent reduce [none 'SERVERSAY none tstring]) | metamodline (insert tevent reduce [none 'METAMOD none tstring]) | adminmodline (insert tevent reduce [none 'ADMINMOD none tstring]) | "Log file closed^/" (insert tevent reduce [none 'LOGEND none none]) | z: thru "^/" y: (copy/part z y) ] logline: [ (clear tevent) "^/" | prefix comment | prefix event (if not empty? tevent [insert/only tail tlog copy tevent]) ] logfile: [ any logline ] set 'hl-parse-log-line func [line][ line: replace/all copy line "^@" "" if line/1 <> #"L" [ line: copy skip line 8 ] if #"^/" <> last line [ line: join line "^/" ] parse/all line logline return tevent ] set 'hl-parse-log-file func [file][ if file? file [ file: read file ] parse/all file logfile return tlog ] ]