rendered paste body################################################################################
# #
# GameFAQs - Game Info Pzs-ng Plug-in v1.5 #
# by Meij <meijie@gmail.com> #
# #
################################################################################
#
# Description:
# - Announce information obtained from gamefaqs.com on new releases.
#
# Installation:
# 1. Copy this file (GameFAQs.tcl) into your pzs-ng sitebots 'plugins' folder.
#
# 2. Edit the configuration options below.
#
# 3. Add the following to your eggdrop.conf:
# source pzs-ng/plugins/GameFAQs.tcl
#
# 4. Add the following to dZSbot.conf:
# set disable(GAMEFAQS) 0
# set disable(GAMEFAQS-PRE) 0
# set disable(GAMEFAQS-MSG) 0
# set variables(GAMEFAQS) "$variables(NEWDIR) %gamefaqs_title %gamefaqs_rating_users %gamefaqs_rating_internet %gamefaqs_rating %gamefaqs_genre %gamefaqs_players %gamefaqs_developer {%gamefaqs_region_title %gamefaqs_region_publisher %gamefaqs_region_date %gamefaqs_region} %gamefaqs_url %gamefaqs_system %gamefaqs_esrb"
# set variables(GAMEFAQS-PRE) "$variables(PRE) %gamefaqs_title %gamefaqs_rating_users %gamefaqs_rating_internet %gamefaqs_rating %gamefaqs_genre %gamefaqs_players %gamefaqs_developer {%gamefaqs_region_title %gamefaqs_region_publisher %gamefaqs_region_date %gamefaqs_region} %gamefaqs_url %gamefaqs_system %gamefaqs_esrb"
# set variables(GAMEFAQS-MSG) "%gamefaqs_title %gamefaqs_rating_users %gamefaqs_rating_internet %gamefaqs_rating %gamefaqs_genre %gamefaqs_players %gamefaqs_developer {%gamefaqs_region_title %gamefaqs_region_publisher %gamefaqs_region_date %gamefaqs_region} %gamefaqs_url %gamefaqs_system %gamefaqs_esrb"
#
# set zeroconvert(%gamefaqs_title) "N/A"
# set zeroconvert(%gamefaqs_rating_users) "-"
# set zeroconvert(%gamefaqs_rating_internet) "-"
# set zeroconvert(%gamefaqs_rating) "-"
# set zeroconvert(%gamefaqs_genre) "N/A"
# set zeroconvert(%gamefaqs_players) "?"
# set zeroconvert(%gamefaqs_developer) "N/A"
# set zeroconvert(%gamefaqs_region_title) "N/A"
# set zeroconvert(%gamefaqs_region_publisher) "N/A"
# set zeroconvert(%gamefaqs_region_date) "N/A"
# set zeroconvert(%gamefaqs_region) "N/A"
# set zeroconvert(%gamefaqs_url) "N/A"
# set zeroconvert(%gamefaqs_system) "N/A"
#
# 5. Add the following to your theme file (.zst).
# announce.GAMEFAQS = "[%b{GAME-INFO}][%section] %b{%gamefaqs_title} %gamefaqs_rating_internet/10 URL: %gamefaqs_url\n[%b{GAME-INFO}][%section] Release Date: %loop1"
# announce.GAMEFAQS_LOOP1 = "%gamefaqs_region: %gamefaqs_region_date%splitter"
#
# announce.GAMEFAQS-PRE = "[%b{GAME-INFO}][%section] %b{%gamefaqs_title} %gamefaqs_rating_internet/10 URL: %gamefaqs_url\n[%b{GAME-INFO}][%section] Release Date: %loop1"
# announce.GAMEFAQS-PRE_LOOP1 = "%gamefaqs_region: %gamefaqs_region_date%splitter"
#
# announce.GAMEFAQS-MSG = "[%b{GAME-INFO}] %b{%gamefaqs_title} %gamefaqs_rating_internet/10 URL: %gamefaqs_url\n[%b{GAME-INFO}][%section] Release Date: %loop1"
# announce.GAMEFAQS-MSG_LOOP1 = "%gamefaqs_region: %gamefaqs_region_date%splitter"
#
# 6. Rehash or restart your eggdrop for the changes to take effect.
#
#
# System Names & Numbers:
#
# Num System | Num System | Num System
#--------------------------------------------------------------------------------
# 0 All Platforms | 1 Dreamcast | 2 Game Boy
# 3 NeoGeo Pocket Color | 4 Nintendo 64 | 5 PC
# 6 PlayStation | 7 PlayStation 2 | 8 Saturn
# 9 Game Boy Color | 10 Genesis | 11 GameCube
# 12 Game Boy Advance | 13 Xbox | 14 Nuon
# 15 3DO | 16 GameGear | 17 Jaguar
# 18 NeoGeo | 19 NES | 20 Sega Master System
# 21 SNES | 22 TurboGrafx-16 | 23 WonderSwan Color
# 24 Amiga | 25 Apple II | 26 Arcade Games
# 27 Arcadia 2001 | 28 Atari 2600 | 29 Atari 5200
# 30 Atari 7800 | 31 Atari 8-bit | 32 BBS Door
# 33 CD-I | 34 Channel F | 35 Colecovision
# 36 Commodore 64 | 37 GP32 | 38 Game.com
# 39 Intellivision | 40 Lynx | 41 MSX
# 42 Macintosh | 43 Microvision | 44 Odyssey^2
# 45 PC-FX | 46 Playdia | 47 Unix/Linux
# 49 Vectrex | 48 VIC-20 | 50 VirtualBoy
# 1000 All | 1002 Sega CD | 1003 Sega 32X
# 1004 Jaguar CD | 1005 Turbo CD | 1006 N-Gage
# 1007 Neo-Geo CD | 1008 Famicom Disc System | 1009 Pinball
# 1010 Online-Only/Web | 1011 Odyssey | 1012 Nintendo 64DD
# 1013 e-Reader | 1014 Pocket PC | 1015 Palm OS
# 1017 SG-1000 | 1018 OS/2 | 1019 Redemption
# 1020 APF-*1000/IM | 1021 Astrocade | 1022 WonderSwan
# 1023 DVD Player | 1024 PSP | 1025 Mobile
# 1026 DS | 1027 Zodiac | 1028 PlayStation 3
# 1029 Xbox 360 | 1030 Gizmondo | 1031 Wii
# 1032 Sharp X68000 | 1033 NEC PC98 | 1034 Atari ST
# 1035 Amstrad CPC | 1036 Tandy Color Computer| 1037 Oric 1/Atmos
# 1038 Commodore PET | 1039 Mattel Aquarius | 1040 EACA Colour Genie 2000
# 1041 FM Towns | 1042 Adventurevision | 1043 SuperVision
# 1044 CPS Changer | 1045 RCA Studio II | 1046 LaserActive
# 1047 Interton VC4000 | 1048 CreatiVision
#
#################################################################################
namespace eval ::ngBot::GameFAQs {
variable events
variable gamefaqs
## Config Settings ###############################
## Sections to be active in:
## Format: {Num Path}
##
## Wheres Num is the system number from the above graph, and the path
## is path of the section (wildcards accepted).
set gamefaqs(sections) { {12 /site/incoming/gba/} {13 /site/incoming/xbox} {7 /site/incoming/ps2} {0 /site/requests/} }
##
## Timeout in milliseconds.
set gamefaqs(timeout) 10000
##
## Channel trigger (Leave blank to disable)
set gamefaqs(ctrigger) "!game"
##
## Private message trigger (Leave blank to disable)
set gamefaqs(ptrigger) ""
##
## Date format (URL: http://tcl.tk/man/tcl8.3/TclCmd/clock.htm)
set gamefaqs(date) "%Y-%m-%d"
##
## Skip announce for these directories.
set gamefaqs(ignore_dirs) {cd[0-9] dis[ck][0-9] dvd[0-9] codec cover covers extra extras sample subs vobsub vobsubs}
##
## Pre line regexp
## We need to reconstruct the full path to the release. Since not all
## pre scripts use the same format we'll use regexp to extract what we
## need from the pre logline and reconstuct it ourselves.
##
## Default f00-pre example:
set gamefaqs(pre-regexp) {^"(.[^"]+)" ".[^"]*" ".[^"]*" "(.[^"]+)"}
set gamefaqs(pre-path) "%2/%1"
##
## Default eur0-pre example:
#set gamefaqs(pre-regexp) {^"(.[^"]+)"}
#set gamefaqs(pre-path) "%1"
##
##################################################
set events [list "NEWDIR" "PRE"]
variable scriptName [namespace current]::LogEvent
bind evnt -|- prerehash [namespace current]::DeInit
}
proc ::ngBot::GameFAQs::Init {args} {
global postcommand
variable events
variable gamefaqs
variable scriptName
if {[catch {package require http}] != 0} {
[namespace current]::Error "\"http\" package not found, unloading script."
::ngBot::GameFAQs::DeInit
return
}
## Register the event handler.
foreach event $events {
lappend postcommand($event) $scriptName
}
if {([info exists gamefaqs(ctrigger)]) && (![string equal $gamefaqs(ctrigger) ""])} {
bind pub -|- $gamefaqs(ctrigger) [namespace current]::Trigger
}
if {([info exists gamefaqs(ptrigger)]) && (![string equal $gamefaqs(ptrigger) ""])} {
bind msg -|- $gamefaqs(ptrigger) [namespace current]::Trigger
}
putlog "\[ngBot\] GameFAQs :: Loaded successfully."
}
proc ::ngBot::GameFAQs::DeInit {args} {
global postcommand
variable events
variable gamefaqs
variable scriptName
## Remove the script event from postcommand.
foreach event $events {
if {[info exists postcommand($event)] && [set pos [lsearch -exact $postcommand($event) $scriptName]] != -1} {
set postcommand($event) [lreplace $postcommand($event) $pos $pos]
}
}
catch {unbind pub -|- $gamefaqs(ctrigger) [namespace current]::Trigger}
catch {unbind msg -|- $gamefaqs(ptrigger) [namespace current]::Trigger}
catch {unbind evnt -|- prerehash [namespace current]::DeInit}
namespace delete [namespace current]
}
proc ::ngBot::GameFAQs::Error {error} {
putlog "\[ngBot\] GameFAQs :: Error: $error"
}
proc ::ngBot::GameFAQs::ConvertDate {string} {
variable gamefaqs
if {[catch {clock format [clock scan $string] -format $gamefaqs(date)} result] == 0} {
set string $result
}
return $string
}
proc ::ngBot::GameFAQs::Trigger {args} {
global lastbind
if {[llength $args] == 5} {
checkchan [lindex $args 2] [lindex $args 3]
}
set text [lindex $args [expr { [llength $args] - 1 }]]
set target [lindex $args [expr { [llength $args] - 2 }]]
set platform [[namespace current]::SelectPlatform [lindex [split $text] 0]]
if {$platform != 0} {
set text [join [lrange [split $text] 1 end]]
}
if {[string equal $text ""]} {
sndone $target "GameFAQs Syntax :: $lastbind \[platform\] <string> (eg: $lastbind pc diablo 2)"
return 1
}
if {[catch {[namespace current]::FindInfo $text $platform [list]} logData] != 0} {
sndone $target "GameFAQs Error :: \"$logData\""
return 0
}
sndone $target [ng_format "GAMEFAQS-MSG" "none" $logData]
return 1
}
proc ::ngBot::GameFAQs::LogEvent {event section logData} {
variable gamefaqs
if {[string compare -nocase $event "NEWDIR"] == 0} {
set target "GAMEFAQS"
set release [lindex $logData 0]
} else {
set target "GAMEFAQS-PRE"
if {(![info exists gamefaqs(pre-regexp)]) || (![info exists gamefaqs(pre-path)])} {
[namespace current]::Error "Your pre-regexp or pre-path variables are not set"
return 0
}
if {[catch {regexp -inline -nocase -- $gamefaqs(pre-regexp) $logData} error] != 0} {
[namespace current]::Error $error
return 0
}
if {[set cookies [regexp -inline -all -- {%([0-9]+)} $gamefaqs(pre-path)]] == ""} {
[namespace current]::Error "Your pre-path contains no valid cookies"
return 0
}
set release $gamefaqs(pre-path)
foreach {cookie number} $cookies {
regsub -- $cookie $release [lindex $error $number] release
}
}
## Check the release directory is ignored.
foreach ignore [split $gamefaqs(ignore_dirs) " "] {
if {[string match -nocase $ignore [file tail $release]]} {
return 1
}
}
foreach {platform path} [join $gamefaqs(sections)] {
if {[string match -nocase "$path*" $release]} {
if {[catch {[namespace current]::FindInfo [file tail $release] $platform $logData} logData] != 0} {
[namespace current]::Error "$logData. ($release)"
return 0
}
sndall $target $section [ng_format $target $section $logData]
break
}
}
return 1
}
proc ::ngBot::GameFAQs::FindInfo {string platform logData} {
set output_order [list title rating_users rating_internet rating genre \
players developer release_data url system esrb]
set string [[namespace current]::Cleanup $string]
::http::config -useragent "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7"
array set info [[namespace current]::FindGame $string $platform]
if {[info exists info(url)]} {
set info(url) "http://www.gamefaqs.com$info(url)"
array set info [[namespace current]::GetGame $info(url)]
if {[info exists info(rating_url)]} {
array set info [[namespace current]::GetRating $info(rating_url)]
}
}
foreach key $output_order {
if {(![info exists info($key)]) || \
([string equal -nocase $info($key) " "])} {
set info($key) ""
}
lappend logData $info($key)
}
return $logData
}
proc ::ngBot::GameFAQs::FindGame {string platform} {
variable gamefaqs
set token [::http::geturl "http://www.gamefaqs.com/search/index.html?[::http::formatQuery platform $platform game $string]" -timeout $gamefaqs(timeout)]
set data [::http::data $token]
if {![regexp -indices -nocase -- {<div class="head"><h1>Best Matches</h1></div>} $data pos]} {
return -code error "No results found"
}
array set info [list]
regexp -nocase -start [lindex $pos 1] -- {<a href="(.*?)">(.*?)</a></td>} $data -> info(url) info(title)
return [array get info]
}
proc ::ngBot::GameFAQs::GetGame {url {loop 0}} {
variable gamefaqs
set token [::http::geturl $url -timeout $gamefaqs(timeout)]
upvar #0 $token state
array set meta $state(meta)
if {[info exists meta(Location)]} {
set token [::http::geturl $meta(Location) -timeout $gamefaqs(timeout)]
set info(url) $meta(Location)
}
set data [::http::data $token]
array set info [list]
regexp -nocase -- {<div class="crumbs">[\s\n\r]+<a href=".[^"]+">(.[^<]+)</a>} $data -> info(system)
if {[regexp -nocase -- {<div class="details">(.*?)</div>} $data -> title_data]} {
set title_details [regexp -inline -nocase -all -- {<p>(.*?):.*?<b>(.*?)</b>.[^<]*</p>} $title_data]
if {[llength $title_details] > 0} {
foreach {junk name value} $title_details {
switch -exact [string tolower $name] {
"genre" {
set value [string map { ">" " > " } $value]
set info(genre) [[namespace current]::ToTitle $value]
}
"developer" {
regexp -nocase -- {<a href=".*?">(.*?)</a>} $value -> info(developer)
}
## has this been removed ?
"number of players" {
set info(players) [[namespace current]::ToTitle $value]
}
"esrb rating" {
set info(esrb) $value
}
}
}
}
}
if {[regexp -nocase -- {<table class="release">(.*?)</table>} $data -> release_data]} {
set release_details [regexp -inline -nocase -all -- {<th>(.[^<]*)</th>.[^<]*<td>.[^<]*<a href=".[^"]*">(.[^<]*)</a></td>.[^<]*<td.[^>]*>.[\s\t\r\n]*(.[^<]*)</td>.[^<]*<td>.[\s\t\r\n]*(.[^<]*)</td>} $release_data]
if {[llength $release_details] > 0} {
foreach {junk title publisher date region} $release_details {
set date [[namespace current]::ConvertDate $date]
lappend info(release_data) $title $publisher $date $region
}
}
}
regexp -nocase -- {<a href="(.[^"]+)" target="_blank">GameSpot</a>} $data -> info(rating_url)
return [array get info]
}
proc ::ngBot::GameFAQs::GetRating {url} {
variable gamefaqs
set token [::http::geturl $url -timeout $gamefaqs(timeout)]
upvar #0 $token state
array set meta $state(meta)
array set info [list]
if {[info exists meta(Location)]} {
set token [::http::geturl $meta(Location) -timeout $gamefaqs(timeout)]
}
set data [::http::data $token]
regexp -nocase -- {We Say</a><br />[\s\n\r]+<span class=".[^"]*">(.[^<]+)</span>} $data -> info(rating)
regexp -nocase -- {You Say</a><br />[\s\n\r]+<span class=".[^"]*">(.[^<]+)</span>} $data -> info(rating_users)
regexp -nocase -- {They Say</a><br />[\s\n\r]+<span class=".[^"]*">(.[^<]+)</span>} $data -> info(rating_internet)
return [array get info]
}
proc ::ngBot::GameFAQs::ToTitle {text} {
set result [list]
foreach word [split $text " "] {
if {![string is upper $word]} {
set nword [list]
foreach sword [split $word "-"] {
lappend nword [string totitle $sword]
}
set word [join $nword "-"]
}
lappend result $word
}
return [join $result " "]
}
#proc ::ngBot::GameFAQs::Cleanup {release} {
# set release [split $release "-"]
# if {[llength $release] > 1} {
# set release [lrange $release 0 [expr { [llength $release] - 2 }]]
# }
# set release [join [split [join [split [join $release] "."]] "_"]]
# set search ""
# set list {
# "multi??" "multi?" "mu?" "euro" "eur" "jpn" "jap" "usa" "internal" "trainer" "gba" "beta"
# "cracked" "nokia" "gba" "symbianos?" "proper" "multilanguage" "pal" "ntsc" "ps2" "xbox"
# "readnfo" "plus??" "plus?" "repack" "gba" "patch" "ngage" "retail" "arena" "crack" "french"
# "psp" "nds" "gbc" "wsx" "ws" "ngp" "ngpx" "dvd" "xboxdvd" "ps2dvd" "ps2rip" "xboxrip"
# }
# set search [list]
# foreach segment $release {
# set retval [catch { foreach check $list { if {[string match -nocase $check $segment]} { error beep } } }]
# if {$retval == 1} { break }
# lappend search $segment
# }
# return [join $search " "]
#}
proc ::ngBot::GameFAQs::Cleanup {string} {
set string [split [string tolower $string] "-"]
if {[llength $string] > 1} {
set string [lrange $string 0 [expr { [llength $string] - 2 }]]
}
set string [join [split [join $string] "._"]]
set banned {
"multi??" "multi?" "mu?" "euro" "eur" "jpn" "jap" "usa" "internal"
"trainer" "gba" "beta" "cracked" "nokia" "gba" "symbianos?" "proper"
"multilanguage" "pal" "ntsc" "ps2" "xbox" "readnfo" "plus??" "plus?"
"repack" "gba" "patch" "ngage" "retail" "arena" "crack" "french" "psp"
"nds" "gbc" "wsx" "ws" "ngp" "ngpx" "dvd" "xboxdvd" "ps2dvd" "ps2rip"
"xboxrip" "dutch" "german" "nds" "psp" "clonecd" "sfclone" "clonedvd"
}
set i [expr { [llength $string] - 1 }]
foreach match $banned {
if {([set result [lsearch -glob $string $match]] < $i) && ($result != -1)} {
set i $result
incr i -1
}
}
return [lrange $string 0 $i]
}
proc ::ngBot::GameFAQs::SelectPlatform {string} {
array set platforms {
dc 1 gb 2 ngpc 3 n64 4 pc 5
ps 6 ps2 7 sat 8 gbc 9 gen 10
gc 11 gba 12 xbox 13 nuon 14 3do 15
gg 16 jag 17 neo 18 nes 19 sms 20
snes 21 tg16 22 wsc 23 ami 24 apl2 25
arc 26 a2k1 27 2600 28 5200 29 7800 30
a800 31 bbs 32 cdi 33 fair 34 cvis 35
c64 36 gp32 37 gcom 38 intv 39 lynx 40
msx 41 mac 42 mvis 43 o2 44 pcfx 45
pld 46 unix 47 vc20 48 vecx 49 vboy 50
scd 1002 32x 1003 jcd 1004 tcd 1005 nge 1006
ngcd 1007 fds 1008 pbl 1009 web 1010 ody 1011
n64dd 1012 erdr 1013 ppc 1014 pos 1015 sg1 1017
os2 1018 red 1019 apf 1020 ast 1021 ws 1022
dvd 1023 psp 1024 mobile 1025 ds 1026 zod 1027
ps3 1028 x360 1029 giz 1030 wii 1031 x68 1032
pc98 1033 st 1034 cpc 1035 coco 1036 oric 1037
pet 1038 aqu 1039 cg 1040 fmt 1041 adv 1042
sv 1043 cps 1044 s2 1045 la 1046 ivc 1047
vcv 1048
}
set string [string tolower $string]
set platform 0
if {[info exists platforms($string)]} {
set platform $platforms($string)
}
return $platform
}
::ngBot::GameFAQs::Init