Added basic dsrc building

This commit is contained in:
seefo
2018-01-11 20:52:36 -05:00
parent 709cca43a5
commit abd1e4da23
174 changed files with 29834 additions and 41 deletions

5
.dockerignore Normal file
View File

@@ -0,0 +1,5 @@
dsrc/*
gameserver/*
src/*
.git/*
!src/external/3rd/library/curl/

View File

@@ -4,3 +4,9 @@ basedir=$PWD
# ensure that repo has been setup
$basedir/utils/initial_setup.sh
# run the docker image and build the source
docker run -v $basedir/gameserver/:/swg/:z -v $basedir/dsrc/:/swg/dsrc/:z -e SWG_BUILD_DSRC=TRUE swg-runtime
# cleanup any artifacts
rm -rf $basedir/gameserver/dsrc/*
rm $basedir/gameserver/core

37
gameserver/Dockerfile Normal file
View File

@@ -0,0 +1,37 @@
FROM debian:jessie
MAINTAINER seefo
# install build dependencies
run apt-get update
run dpkg --add-architecture i386 && \
apt-get update && \
apt-get install -y alien rpm libc6:i386 libncurses5:i386 libstdc++6:i386 alien gcc-multilib g++-multilib binutils-multiarch libaio1:i386 libcurl4-gnutls-dev:i386 libpcre3:i386 libxml2:i386 libaio1 unixodbc
# add redists
add ./utils/redist/ /redist/
# install redists
run fakeroot alien --target=amd64 -i /redist/oracle-instantclient12.1-basic-12.1.0.2.0-1.i386.rpm
run fakeroot alien --target=amd64 -i /redist/oracle-instantclient12.1-devel-12.1.0.2.0-1.i386.rpm
run fakeroot alien --target=amd64 -i /redist/oracle-instantclient12.1-sqlplus-12.1.0.2.0-1.i386.rpm
# install java
run cd /redist/ && \
tar -xvzf IBMJava2-SDK-1.4.2-13.18.tgz && \
mv IBMJava2-142/ /opt && \
ln -s /opt/IBMJava2-142 /usr/java
# build and install curl
add src/external/3rd/library/curl/curl-7.45.0 /redist/curl/
run cd /redist/curl && ./configure && make && make install
# env variables
ENV JAVA_HOME /usr/java
ENV ORACLE_HOME /usr/lib/oracle/12.1/client
run export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/oracle/12.1/client/lib:/usr/include/oracle/12.1/client
run ldconfig
run apt-get install -y bc python-ply
# entrypoint
ENTRYPOINT cd /swg/ && ./utils/entrypoint.sh

View File

@@ -1,23 +0,0 @@
#!/bin/bash
NODE_COUNT=
echo 'Generating node list...'
if [ ! -d ./exe/ ]; then
mkdir ./exe/
mkdir ./exe/linux
fi
read -p "How many nodes are in this cluster? " NODE_COUNT
echo "[TaskManager]" > ./exe/linux/nodes.cfg
# For each node, prompt for an ip.
for i in $(seq 0 $(expr $NODE_COUNT - 1))
do
read -p "node$i ip: (Try using what is specified for your hostname in /etc/hosts " CURRENT_NODE_IP
echo "node$i=$CURRENT_NODE_IP" >> ./exe/linux/nodes.cfg
done

View File

@@ -12,7 +12,7 @@ for filename in $filenames; do
mkdir -p $(dirname $ofilename)
if [[ -e $ofilename && $filename -nt $ofilename ]] || [ ! -e $ofilename ]; then
result=$(./exe/linux/bin/Miff -i "$filename" -o "$ofilename" 2>&1)
result=$(./bin/Miff -i "$filename" -o "$ofilename" 2>&1)
if [[ ! "$result" =~ .*successfully.* ]]; then
printf "\r$result\n\n"

View File

@@ -29,7 +29,7 @@ def build_table(type, objs):
if not path.exists(path.dirname(ifffile)):
makedirs(path.dirname(ifffile))
crc_call = ['./tools/buildCrcStringTable.pl', '-t', tabfile, ifffile]
crc_call = ['./utils/tools/buildCrcStringTable.pl', '-t', tabfile, ifffile]
p = Popen(crc_call, stdin=PIPE, stdout=PIPE)

View File

@@ -34,7 +34,7 @@ if not path.exists(path.dirname(tabfile)):
if not path.exists(path.dirname(ifffile)):
makedirs(path.dirname(ifffile))
crc_call = ['./tools/buildCrcStringTable.pl', '-t', tabfile, ifffile]
crc_call = ['./utils/tools/buildCrcStringTable.pl', '-t', tabfile, ifffile]
p = Popen(crc_call, stdin=PIPE, stdout=PIPE)

View File

@@ -17,7 +17,7 @@ for filename in ${filenames[@]}; do
mkdir -p $(dirname $ofilename)
if [[ -e $ofilename && $filename -nt $ofilename ]] || [ ! -e $ofilename ]; then
result=$(./exe/linux/bin/DataTableTool -i "$filename" -o "$ofilename" -- -s SharedFile searchPath10=data/sku.0/sys.shared/compiled/game searchPath10=data/sku.0/sys.server/compiled/game 2>&1)
result=$(./bin/DataTableTool -i "$filename" -o "$ofilename" -- -s SharedFile searchPath10=data/sku.0/sys.shared/compiled/game searchPath10=data/sku.0/sys.server/compiled/game 2>&1)
if [[ ! $result =~ .*SUCCESS.* ]]; then
printf "\r$filename\n"

View File

@@ -12,7 +12,7 @@ compile () {
mkdir -p $(dirname $ofilename)
if [[ -e $ofilename && $filename -nt $ofilename ]] || [ ! -e $ofilename ]; then
result=$(./exe/linux/bin/TemplateCompiler -compile "$filename" 2>&1)
result=$(./bin/TemplateCompiler -compile "$filename" 2>&1)
if [[ ! -z $result ]]; then
printf "\r$filename\n"

15
gameserver/utils/entrypoint.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
basedir=$PWD
if [[ -z "${SWG_BUILD_DSRC}" ]]; then
echo "Running Server"
else
echo "Building DSRC"
$basedir/utils/content/build_miff.sh
$basedir/utils/content/build_tab.sh
$basedir/utils/content/build_tpf_multi.sh
$basedir/utils/content/build_object_template_crc_string_tables.py
$basedir/utils/content/build_quest_crc_string_tables.py
echo "Done building DSRC"
fi

View File

@@ -0,0 +1,146 @@
#!/usr/bin/perl -w
use File::Find;
use BuildFunctions;
###
# Copyright (C)2000-2002 Sony Online Entertainment Inc.
# All Rights Reserved
#
# Title: AutomatedDailyBuild.pl
# Description: Forces a sync to current, syncs to head, builds all_Client, SWGGameServer, PlanetServer, and SwgLoadServer and check for writable files in the src directory then emails log files to gmcdaniel.
# @author $Author: gmcdaniel $
# @version $Revision: #17 $
##
##
# This subroutine finds any non-authorized writable files in a passed directory
sub Find_Writable
{
if (-d $_)
{
# found a directory entry
# prune the directory if it's one we want to ignore
if (m/^(compile)$/)
{
#prune it
$File::Find::prune = 1;
}
}
elsif (-f and -w $_)
{ if (!m/^.*(aps|ncb|opt|plg)$/)
{
print "n $File::Find::name\n";
print Logfile "n $File::Find::name\n";
}
}
} # End of sub Find_Writable
########## MAIN ##########
##
# Delete compile directory for clean build
system("c:\\4nt302\\4nt /c del /s /y ..\\src\\compile");
#
## End of Delete compile directory for clean build
##
# Sync Code to Head
print ("Beginning Sync to Head...\n");
# sync client that points to d:\workdaily
system ("p4 -c gmcdaniel-wxp-gmcdaniel-build-station-machine_daily_build sync //depot/swg...\#head");
print ("Sync Complete\n");
print ("\n");
print ("\n");
#
## End of Sync Code to Head
##
# Forced Code
print ("Beginning Forced Sync...\n");
# sync client that points to d:\workdaily
system ("p4 -c gmcdaniel-wxp-gmcdaniel-build-station-machine_daily_build sync -f //depot/swg...\#have");
print ("Sync Complete\n");
print ("\n");
print ("\n");
#
## End of Forced Sync
##
# Build Projects and Check for Errors
build_project ("_all_client");
Check_For_Warnings_and_Errors("_all_client");
#build_project ("PlanetServer");
#Check_For_Warnings_and_Errors("PlanetServer");
#build_project ("SwgGameServer");
#Check_For_Warnings_and_Errors("SwgGameServer");
#build_project ("SwgLoadClient");
#Check_For_Warnings_and_Errors("SwgLoadClient");
#
## End of Build Projects and Check for Errors
##
# Check for any non-authorized writable files in the /swg/current/src directory and email the results
### Email addresses
#$gmcdaniel = "gmcdaniel\@soe.sony.com";
#$writable_files_log = "WritableFiles.log";
#print ("Checking for writable files...\n");
#open (Logfile, ">d:\\buildlogs\\$writable_files_log") || die "Sorry, I couldn't create $writable_files_log";
#print Logfile "The writable files that were found:\n";
# do a find
#$search_path = "..\\src";
#@ARGV = ($search_path);
#find(\&Find_Writable, @ARGV);
#close (Logfile);
#$writable_test_time_and_date = get_time_and_date();
#$date_stamp = get_date();
#system ("copy d:\\buildlogs\\$writable_files_log d:\\buildlogs\\WritableFiles_$writable_test_time_and_date.log");
#print ("Checking for writable files completed\n");
#print ("\n");
#print ("\n");
#system ("postie -host:sdt-mx1.station.sony.com -to:$gmcdaniel -from:$gmcdaniel -s:\"Writable Files Results $date_stamp\" -nomsg -file:d:\\buildlogs\\WritableFiles_$writable_test_time_and_date.log");
#
## End of Check for any non-authorized writable files in the /swg/current/src directory and email the results
########## END OF MAIN ##########

View File

@@ -0,0 +1,45 @@
#!/usr/bin/perl -w
########## MAIN ##########
##
#
print ("Synching to head\n");
system ("p4 sync \#head");
print ("End of sync to head\n");
print ("Cleaning process...\n");
system ("make -C ./work/swg/current/src/build/linux/ cleanall");
print ("Cleaning Process Complete\n");
print ("Starting Debug Server Build\n");
system ("make -C ./work/swg/current/src/build/linux/ debug 2>&1 | tee grant debug.log");
print ("Debug Server Build Complete\n");
print ("\n");
print ("Cleaning process...\n");
system ("make -C ./work/swg/current/src/build/linux/ cleanall");
print ("Cleaning Process Complete\n");
print ("Starting Release Server Build\n");
system ("make -C ./work/swg/current/src/build/linux/ release 2>&1 | tee grantrelease.log");
print ("Release Server Build Complete\n");
print ("Mailing debug log");
system ("mail -s \"[BUILDLOG] Daily Debug Server Log\" gmcdaniel\@soe.sony.com cmayer\@soe.sony.com asommers\@soe.sony.com jgrills\@soe.sony.com jbrack\@soe.sony.com <grantdebug.log");
print ("Mailing release log");
system ("mail -s \"[BUILDLOG] Daily Release Server Log\" gmcdaniel\@soe.sony.com cmayer\@soe.sony.com asommers\@soe.sony.com jgrills\@soe.sony.com jbrack\@soe.sony.com <grantrelease.log");
#
##
########## END OF MAIN ##########

View File

@@ -0,0 +1,86 @@
#!/usr/bin/perl
use strict;
use warnings;
sub usage
{
die "usage: $0 [-i] [-t] perforce_file_spec start_changelist end_changelist\n" .
"\t-i show internal notes\n" .
"\t-t show testplan\n";
}
my $showInternal = 0;
my $showTestplan = 0;
usage() if (@ARGV < 3);
while ($ARGV[0] eq "-i" || $ARGV[0] eq "-t")
{
$showInternal = 1 if ($ARGV[0] eq "-i");
$showTestplan = 1 if ($ARGV[0] eq "-t");
shift;
}
my $spec = shift;
my $first = shift;
my $last = shift;
open(P4, "p4 changes $spec\@$first,$last |");
my @changes = <P4>;
close(P4);
foreach (@changes)
{
chomp;
s/'.*//;
my $changeline = $_;
s/^Change //;
s/ .*//;
my $change = $_;
open(P4, "p4 describe -s $change |");
my $public = "";
my $internal = "";
my $testplan = "";
my $junk = "";
my $section = "junk";
while (<P4>)
{
if (s/^\t//)
{
if (/\[public\]/)
{
$section = "public";
}
elsif (/\[internal\]/)
{
$section = "internal";
}
elsif (/\[testplan\]/)
{
$section = "testplan";
}
elsif (/\[/)
{
$section = "junk";
}
elsif ($_ ne "\n")
{
$public .= $_ if ($section eq "public");
$internal .= $_ if ($section eq "internal");
$testplan .= $_ if ($section eq "testplan");
}
}
else
{
$section = "junk";
}
}
close(P4);
print $changeline,"\n" if ($public ne "" || ($showInternal && $internal ne "") || ($showTestplan && $testplan ne ""));
print "[public]\n", $public, "\n" if ($public ne "");
print "[internal]\n", $internal, "\n" if ($showInternal && $internal ne "");
print "[testplan]\n", $testplan, "\n" if ($showTestplan && $testplan ne "");
print "\n\n" if ($public ne "" || $internal ne "" || $testplan ne "");
}

1603
gameserver/utils/tools/BuildDsp.pl Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,278 @@
package BuildFunctions;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(build_project Check_For_Warnings_and_Errors get_time_and_date get_date);
###
# Copyright (C)2000-2002 Sony Online Entertainment Inc.
# All Rights Reserved
#
# Title: BuildFunctions.pl
# Description: This file contains the various functions used by the different build scripts.
# @author $Author: gmcdaniel $
# @version $Revision: #1 $
##
#todo Possible failure points that I need to fix. The ResultsLogfile file can fail to be opened in one sub but still try to be written to in Check_Logfile_For_Warnings_and_Errors
#todo Bad coding to call ResultsLogFile without acutally passing it in to the sub? Probably
##
# This subroutine builds the passed project. It is passed the project name, the string for the project to build, and the project type (release or debug)
sub build
{
print ("Beginning $_[1] build...\n");
system("msdev ..\\src\\build\\win32\\swg.dsw /MAKE \"$_[1]\" /y3 /REBUILD /OUT d:\\buildlogs\\$_[0]_$_[2].log");
print ("$_[1] build complete\n");
print ("\n");
$timestamp = get_time_and_date();
$timeStamped_Log = $_[0]."_".$_[2]."_".$timestamp.".log";
system ("copy d:\\buildlogs\\$_[0]_$_[2].log d:\\buildlogs\\$timeStamped_Log");
print ("\n");
print ("\n");
} # End of sub build
##
# This subroutine calls the build subroutine to build both the release and debug versions of the project that is passed
sub build_project
{
$project = $_[0]." - Win32 Release";
$type = "Release";
build($_[0],$project,$type);
$project = $_[0]." - Win32 Debug";
$type = "Debug";
build($_[0],$project,$type);
$project = $_[0]." - Win32 Optimized";
$type = "Optimized";
build($_[0],$project,$type);
} # End of sub build_project
##
# This subroutine returns the current local time and date
sub get_time_and_date
{
($sec, $min, $hour, $day, $month, $year) = (localtime) [0,1,2,3,4,5];
$month = $month + 1;
$year = $year + 1900;
$dayandtime = $month."_".$day."_".$year."__".$hour."_".$min."_".$sec;
return $dayandtime;
} # End of sub get_time_and_date
##
# This subroutine returns the current local date
sub get_date
{
($day, $month, $year) = (localtime) [3,4,5];
$month = $month + 1;
$year = $year + 1900;
$date = $month."/".$day."/".$year;
return $date;
} # End of sub get_date
##
# This subroutine checks for warnings and errors in the build logs. If there is an error it returns true otherwise it returns false.
# It takes the name the logfile to check and the resulting exe or project name as input.
sub Check_Logfile_For_Warnings_and_Errors
{
$third_to_last_line = "test_line_3";
$second_to_last_line = "test_line_2";
open (Logfile,"d:\\buildlogs\\$_[0]") || die "Cannot open $_[0] for reading.";
while (<Logfile>)
{
chomp;
$third_to_last_line = $second_to_last_line;
$second_to_last_line = $_;
}
close (Logfile) || die "can't close $_[0]";
print ("\n");
print ("$third_to_last_line\n");
print ("$second_to_last_line\n");
print ResultsLogfile ("$third_to_last_line\n");
print ResultsLogfile ("$second_to_last_line\n");
print ResultsLogfile ("\n");
$search_for_errors= "0 error";
$search_for_warnings= "0 warning";
$match=-1;
#check for 0 errors.
if (index($third_to_last_line, $search_for_errors,$match) > -1) {
print ("No errors Found in $_[0]\n");
print ("\n");
#check for warnings
if (index($third_to_last_line, $search_for_warnings,$match) > -1) {
#no warnings or errors found
print ("No Warnings Found in $_[0]\n");
print ("\n");
return "false";
}
#a warning was found
print ("Warning Found in $_[0]\n");
print ("\n");
return "true";
}
#an error was found
else {
print ("Error Found in $_[0]\n");
print ("\n");
return "true";
}
} # End of sub Check_Logfile_For_Warnings_and_Errors
##
# This subroutine checks for warnings and errors in the build logs. If there is an error or warning it notifies QA and the lead programmers.
# If there is not an error or warning then the build log is just sent to QA.
# It takes the name of the project and the resulting exe or project name as input.
sub Check_For_Warnings_and_Errors
{
print ("Checking for errors and warnings...\n");
print ("\n");
# create file to store warnings and errors for inclusion in body of email.
open (ResultsLogfile, ">d:\\buildlogs\\$_[0]Results.log") || die "Sorry, I couldn't create $_[0]Results.log";
# Prints to results file for easier email formatting
print ResultsLogfile ("\n");
print ResultsLogfile ("Release Build:\n");
# Checks for errors or warnings in the release build
$Logfile_to_check = $_[0]."_Release.log";
$ReleaseError = Check_Logfile_For_Warnings_and_Errors($Logfile_to_check);
# Prints to results file for easier email formatting
print ResultsLogfile ("\n");
print ResultsLogfile ("Debug Build:\n");
# Checks for errors or warnings in the debug build
$Logfile_to_check = $_[0]."_Debug.log";
$DebugError = Check_Logfile_For_Warnings_and_Errors($Logfile_to_check);
# Prints to results file for easier email formatting
print ResultsLogfile ("\n");
print ResultsLogfile ("Optimized Build:\n");
# Checks for errors or warnings in the debug build
$Logfile_to_check = $_[0]."_Optimized.log";
$OptimizedError = Check_Logfile_For_Warnings_and_Errors($Logfile_to_check);
# Closes file used for the number of errors and warnings
close (ResultsLogfile);
# Email addresses
$gmcdaniel = "gmcdaniel\@soe.sony.com";
$jbrack = "jbrack\@soe.sony.com";
$jgrills = "jgrills\@soe.sony.com";
$asommers = "asommers\@soe.sony.com";
$cmayer = "cmayer\@soe.sony.com";
$prog_leads = "-to:$gmcdaniel -to:$jgrills -to:$cmayer -to:$asommers -cc:$jbrack";
$date_stamp = get_date();
if ($ReleaseError eq "true")
{
print ("Error or warning found in $_[0] Release Log. Emailing appropriate people.\n");
# Email the results to Programmer Leads and QA
system ("postie -host:sdt-mx1.station.sony.com $prog_leads -from:$gmcdaniel -s:\"[BUILDLOG] Errors or Warnings in Daily $_[0] Build Logs $date_stamp\" -nomsg -file:d:\\buildlogs\\$_[0]Results.log -a:d:\\buildlogs\\$_[0]_Release.log -a:d:\\buildlogs\\$_[0]_Debug.log -a:d:\\buildlogs\\$_[0]_Optimized.log");
}
elsif ($DebugError eq "true")
{
print ("Error or warning found in $_[0] Debug Log. Emailing appropriate people.\n");
# Email the results to Programmer Leads and QA
system ("postie -host:sdt-mx1.station.sony.com $prog_leads -from:$gmcdaniel -s:\"[BUILDLOG] Errors or Warnings in Daily $_[0] Build Logs $date_stamp\" -nomsg -file:d:\\buildlogs\\$_[0]Results.log -a:d:\\buildlogs\\$_[0]_Release.log -a:d:\\buildlogs\\$_[0]_Debug.log -a:d:\\buildlogs\\$_[0]_Optimized.log");
}
elsif ($OptimizedError eq "true")
{
print ("Error or warning found in $_[0] Optimized Log. Emailing appropriate people.\n");
# Email the results to Programmer Leads and QA
system ("postie -host:sdt-mx1.station.sony.com $prog_leads -from:$gmcdaniel -s:\"[BUILDLOG] Errors or Warnings in Daily $_[0] Build Logs $date_stamp\" -nomsg -file:d:\\buildlogs\\$_[0]Results.log -a:d:\\buildlogs\\$_[0]_Release.log -a:d:\\buildlogs\\$_[0]_Debug.log -a:d:\\buildlogs\\$_[0]_Optimized.log");
}
else
{
print ("No errors or warnings found in $_[0] logs.");
# Email the results to QA and Programmer Leads
system ("postie -host:sdt-mx1.station.sony.com $prog_leads -from:$gmcdaniel -s:\"[BUILDLOG] $_[0] Build Successful $date_stamp\" -nomsg -file:d:\\buildlogs\\$_[0]Results.log");
}
print ("End of errors and warning check for $_[0] logs.\n");
print ("\n");
} # End of sub Check_For_Warnings_and_Errors
1;

View File

@@ -0,0 +1,68 @@
#!/usr/bin/perl
use warnings;
use strict;
sub numerically
{
$a <=> $b;
}
# check command line arguments
if (@ARGV < 2 || ($ARGV[0] =~ /^[-\/]/) || !($ARGV[0] =~ /tre$/i))
{
die "usage: $0 [treefile.tre] [changelist ...]\n";
}
my $tre = shift;
# process all changelists gathering up files for the TRE
print "Processing changelists\n";
my %file;
foreach my $changelist (sort numerically @ARGV)
{
print "\t$changelist\n";
open(P4, "p4 describe -s $changelist |");
while (<P4>)
{
chomp;
if (s%^\.\.\. //depot/swg/live/(data/sku.\d+/sys.(client|shared)/[^\/]+/[^\/]+)/%%)
{
my $prefix = $1;
s/#\d+ .*//;
$file{$_} = "../../$prefix/" . $_;
}
}
close(P4);
}
print"\n";
# generate the tree file response file
print "Generating response file\n";
my $rsp = $tre;
$rsp =~ s/tre$/rsp/i;
open(RSP, ">" . $rsp);
foreach (sort keys %file)
{
print "\t", $_, " @ ", $file{$_}, "\n";
print RSP $_, " @ ", $file{$_}, "\n";
}
close(RSP);
print"\n";
# build the tree file
print "Generating tree file\n";
open(TRE, "TreeFileBuilder -r $rsp $tre |");
print "\t", $_ while (<TRE>);
close(TRE);
print "\n";
# generate the md5sum for the file
print "Generating md5sum\n";
my $md5 = $tre;
$md5 =~ s/tre$/md5/i;
system("md5sum -b $tre > $md5");
open(MD5, $md5);
print "\t", $_ while (<MD5>);
close(MD5);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,240 @@
#! /usr/bin/perl
# ======================================================================
# ======================================================================
use strict;
use warnings;
use File::Copy;
# ======================================================================
# Globals
# ======================================================================
my $oldManifest = "dailyPatchSizeOld.mft";
my $newManifest = "dailyPatchSizeNew.mft";
my $tabFile = "CheckPatchTreeSize.tab";
my $numberOfTabOuts = 15;
my $p4 = "p4";
my $branch;
my $changelist;
my $toolsDir;
my %patchTreeSizes;
my $name = $0;
$name =~ s/^(.*)\\//;
my $logfile = $name;
$logfile =~ s/\.pl$/\.log/;
# ======================================================================
# Subroutines
# ======================================================================
sub getP4dir
{
my $path = $_[0];
open(P4, "p4 where ${path}... |");
my $perforceDir;
while(<P4>)
{
$perforceDir = $_;
}
my @temp = split /\s+/, $perforceDir;
my $retDir = $temp[2];
close(P4);
$retDir =~ s/\.\.\.//g;
return $retDir;
}
sub usage
{
die "\n\t$name <input manifest> <branch> [<changelist>]\n\n";
}
sub readMft
{
my ($filename, $hashRef) = @_;
return if (!-e $filename);
open(MFT, $filename);
my $version = <MFT>;
chomp $version;
$version =~ s/ .*//;
die "unsupported manifest version" if ($version ne "version2");
while(<MFT>)
{
my ($archive, $action, $uncsize, $cmpsize, $checksum, $depotfile, $file) = /^(\S+)\t\S+\t(\S+)\t\S+\t(\S+)\t(\S+)\t(\S+)\t(\S+)\#\d+\t(\S+)\n$/;
next if(!defined $file);
$$hashRef{$depotfile} = [$checksum, $file, $archive, $action, $uncsize, $cmpsize];
}
close(MFT);
}
sub doSync
{
my $oldchangelist = -1;
open(TABFILE, $tabFile) || goto NOTABFILE;
while(<TABFILE>)
{
$oldchangelist = $1 if(/(\d+)\n/);
}
close(TABFILE);
NOTABFILE:
if($oldchangelist == -1)
{
system("$p4 sync //depot/swg/$branch/data/...\@$changelist //depot/swg/$branch/exe/win32/...\@$changelist > $logfile 2>&1");
}
else
{
system("$p4 sync //depot/swg/$branch/data/...\@$oldchangelist,$changelist //depot/swg/$branch/exe/win32/...\@$changelist > $logfile 2>&1");
}
}
sub doExcelOut
{
my @tabOuts;
print "\nTab delimeted output for $branch:\n";
my @skus = (sort keys %patchTreeSizes);
print "Time\t";
foreach (@skus)
{
print "sku.$_\t";
}
print "Changelist\n";
if (-e $tabFile)
{
open(TABFILE, $tabFile);
while(<TABFILE>)
{
push @tabOuts, $_;
}
close(TABFILE);
}
while(@tabOuts > $numberOfTabOuts)
{
shift @tabOuts;
}
foreach (@tabOuts)
{
print;
}
my ($sec, $min, $hr, $day, $mon, $yr) = localtime time;
my $timestamp = sprintf "%4s-%02s-%02s %02s:%02s:%02s", ($yr + 1900), ($mon + 1), $day, $hr, $min, $sec;
my $output = "$timestamp\t";
foreach (@skus)
{
if(exists $patchTreeSizes{$_})
{
$output .= "$patchTreeSizes{$_}\t";
}
else
{
$output .= "0\t";
}
}
$output .= "$changelist\n";
print $output;
open(TABFILE, ">>$tabFile");
print TABFILE $output;
close(TABFILE);
}
sub doChanges
{
my %oldMft;
my %newMft;
my @output;
# Read in the mft file information
readMft($oldManifest, \%oldMft);
readMft($newManifest, \%newMft);
# Check for differences
foreach (keys %newMft)
{
# Only update output if the file is new, or the checksum has changed
next if(exists $oldMft{$_} && $newMft{$_}->[0] eq $oldMft{$_}->[0]);
my $uncDiff = $newMft{$_}->[4] - ((exists $oldMft{$_}) ? $oldMft{$_}->[4] : 0);
my $cmpDiff = $newMft{$_}->[5] - ((exists $oldMft{$_}) ? $oldMft{$_}->[5] : 0);
push @output, join("\t", $_, $newMft{$_}->[1], $newMft{$_}->[2], $newMft{$_}->[3], $uncDiff, $cmpDiff);
}
print "\nFiles changed for $branch:\n";
print join("\t", "Depot Name", "File Name", "Archive", "Action", "Size Added (Uncompressed)", "Size Added (Compressed)"), "\n";
@output = sort { $a cmp $b } @output;
print join "\n", @output;
}
# ======================================================================
# Main
# ======================================================================
usage() if(@ARGV < 2);
my $inputManifest = shift;
$branch = shift;
$changelist = `p4 counter change`;
chomp $changelist;
$changelist = shift if (@ARGV);
$toolsDir = getP4dir("//depot/swg/current/tools/");
my $buildClientDataTreeFiles = getP4dir("//depot/swg/all/tools/build/shared/buildClientDataTreeFiles.pl");
my $exeDir = getP4dir("//depot/swg/$branch/exe/win32/");
chdir $exeDir or die "Could not change directory: $!";
my $pwd = `pwd`;
chomp $pwd;
$ENV{"PWD"} = $pwd;
doSync();
system("perl $buildClientDataTreeFiles --noVerify $newManifest $inputManifest 0 > $logfile");
die "Error creating patch tree - patch_0_00.tre does not exist\n" if(!-e "patch_0_00.tre");
opendir DH, $exeDir;
foreach (sort readdir DH)
{
if(/patch_sku([^_]+)_0_(\d+)\.tre/)
{
$patchTreeSizes{$1} = 0 if (!exists $patchTreeSizes{$1});
$patchTreeSizes{$1} += (-s $_);
}
elsif (/patch_0_(\d+)\.tre/)
{
$patchTreeSizes{0} = 0 if (!exists $patchTreeSizes{0});
$patchTreeSizes{0} += (-s $_);
}
}
closedir DH;
print "Patch tree sizes for $branch:\n";
foreach (sort keys %patchTreeSizes)
{
print "Size of sku$_.tre is: ".$patchTreeSizes{$_}."\n";
}
doExcelOut();
doChanges() if(-e $oldManifest);
move $newManifest, $oldManifest || die "move from $newManifest to $oldManifest failed";

View File

@@ -0,0 +1,195 @@
#! /usr/bin/perl
#
# Fix for Malformed UTF-8 Character error in perl 5.8.0 on linux - "export LANG=en_US"
use warnings;
use strict;
# ======================================================================
# initialization
# setup perforce access environment variables
my $p4 = "p4";
my $branch = "";
my $startingChangelist = 0;
my $endingChangelist;
my $contentLevel = 2;
my $name = $0;
$name =~ s/^(.*)\\//;
my $logfile = $name;
$logfile =~ s/\.pl$/\.log/;
my $programmer = 0;
my $designer = 1;
my $artist = 2;
my $default = $programmer;
my %content;
# ======================================================================
sub usage
{
print STDERR "\nUsage:\n";
print STDERR "\t$name <branch> <starting changelist> <ending changelist>\n";
print STDERR "\n\tending changelist can be a changelist or #head\n";
die "\n";
}
sub getUsers
{
my ($group, $value) = @_;
my $foundUsers = 0;
open(P4, "$p4 group -o $group |");
while(<P4>)
{
$foundUsers = 1 if(/^Users:/);
next if(!$foundUsers);
$content{$1} = $value if(/^\s+(\S+)/);
}
close(P4);
}
# ======================================================================
&usage() if(@ARGV == 0);
my $forceContentLevel;
if(@ARGV == 4)
{
$forceContentLevel = shift @ARGV;
}
&usage() if(@ARGV != 3);
$branch = shift;
$startingChangelist = shift;
$endingChangelist = shift;
my $user;
print "Gathering list of users...\n";
getUsers("swg_programmers", $programmer);
getUsers("swg_leads", $programmer);
getUsers("swg_qa", $programmer);
getUsers("swg_designers", $designer);
getUsers("swg_artists", $artist);
if (defined $forceContentLevel)
{
$contentLevel = $forceContentLevel;
$user = "ContentLevelOverride";
}
else
{
open(P4, "$p4 user -o |") || die "p4 user failed\n";
while(<P4>)
{
if(/^User:\s+(\S+)/)
{
$user = $1;
die "Could not determine if $user is a programmer, designer, or artist\n" if(!exists $content{$user});
$contentLevel = $content{$user};
}
}
close(P4);
}
my $level;
die "Unknown contentLevel: $contentLevel\n" if($contentLevel < 0);
$level = "programmer" if($contentLevel == 0);
$level = "designer" if($contentLevel == 1);
$level = "artist" if($contentLevel == 2);
$level = "specified content only" if($contentLevel >= 3);
print STDERR "Syncing for $user at content level of $level\n";
print STDERR "Getting changes from $startingChangelist to $endingChangelist...\n";
my @changes;
open(P4, "$p4 changes -s submitted //depot/swg/$branch/...\@$startingChangelist,$endingChangelist |") || die "p4 changes failed\n";
while (<P4>)
{
chomp;
s/^Change //;
s/ .*//;
unshift @changes, $_;
}
close(P4);
print STDERR "Scanning changes...\n";
# process all the changelists looking for content files
my %sync;
foreach my $changeList (@changes)
{
# read the change description
my $content = 0;
my $user;
my $notes = "";
my $file;
open(P4, "$p4 -ztag describe -s $changeList |") || die "die: p4 change failed";
while (<P4>)
{
# make the initial decision based on the user
if (/^\.\.\.\s+user\s+(.*)/)
{
$user = $1;
if (!defined $content{$user})
{
# If we don't have the user listed, use default
$content = $default >= $contentLevel ? 1 : 0;
print STDERR "could not determine content status of $1 for changelist $changeList\n";
}
else
{
$content = $content{$user} >= $contentLevel ? 1 : 0;
}
}
# allow overrides in the descriptions
if (/\[\s*no\s+content\s*\]/i)
{
$content = 0;
$notes = " specified [no content]";
}
if (/\[\s*content\s*\]/i)
{
$content = 1;
$notes = " specified [content]";
}
# remember content files
if ($content)
{
$file = $1 if (/^\.\.\.\s+depotFile\d+\s+(.*)/);
$sync{$file} = $1 if (/^\.\.\.\s+rev\d+\s+(.*)/);
}
}
# give summary of this changelist
print "no " if (!$content);
print "content $changeList $user$notes\n";
close(P4);
}
if (scalar(keys %sync) != 0)
{
print STDERR "\nUpdating the client with ", scalar(keys %sync), " file(s)...\n";
open(P4, "| $p4 -x - sync > $logfile 2>&1");
foreach (sort keys %sync)
{
print P4 $_, "#", $sync{$_}, "\n";
}
close(P4);
}
else
{
print STDERR "No files to update.\n";
}
#unlink($logfile);

View File

@@ -0,0 +1,363 @@
#! /usr/bin/perl
use strict;
use warnings;
use Getopt::Std;
use Math::BigInt;
my %player_hash;
# key (player id) => (# trans to, total amt to them, last time to them,
# # trans from, total amt from them, last time from them)
# money_hash is a global hash referece for whatever player we are analyzing
my $money_hash;
my $cnt = 0;
my $sort_val = 0;
my $max_cnt = 0;
my %args;
my $start_time;
my $min_thresh = 0;
my $max_thresh = 0;
my $player_id = 0;
my $start_date;
my $end_date;
my $num_days;
my $total_in = new Math::BigInt '0';
my $total_out = new Math::BigInt '0';
my $num_total_in = new Math::BigInt '0';
my $num_total_out = new Math::BigInt '0';
my @keys;
my $big_zero = new Math::BigInt '0';
my $str_out;
my $abridged = 1;
# Usage
sub usage
{
my $name = $0;
$name =~ s/^(.*)\\//;
print STDERR "\nUsage:\n";
print STDERR "\t$name <optional parameters> <server> <start date> <end date> <player id> ... (as many player ids as you want to scan)\n";
print STDERR "\t\tDate format = yyyy-mm-dd (eg: 2004-06-08)\n";
print STDERR "\t$name <optional parameters> -f <money log file> <player id> ... (as many player ids as you want to scan)\n";
print STDERR "Optional parameters:\n";
print STDERR "\t[-l <num>] [-s <str> | -S <str>] [-n | -a | -t | -N | -A | -T] [-m <str> | -x <str> | -e <str>] [-d]\n";
print STDERR "\t-l <num>\tOnly process <num> lines of log file\n";
print STDERR "\t-s <time>\tStart processing at <time> \(eg \"2004-06-01 17:00:03\"\)\n";
print STDERR "\t-S <time>\tEnd processing at <time>\n";
print STDERR "\t-p \tSort by player id number (default)\n";
print STDERR "\t-n \tSort by number of transactions to the player\n";
print STDERR "\t-a \tSort by total amount of money to the player\n";
print STDERR "\t-t \tSort by time of most recent transaction to the player\n";
print STDERR "\t-N \tSort by number of transactions from the player\n";
print STDERR "\t-A \tSort by total amount of money from the player\n";
print STDERR "\t-T \tSort by time of most recent transaction from the player\n";
print STDERR "\t-m <str>\tSet minimum threshold for sorted parameter\n";
print STDERR "\t-x <str>\tSet maximum threshold for sorted parameter\n";
print STDERR "\t-e <str>\tSet threshold to exactly <num>\n";
print STDERR "\t-d \tShow detailed output\n";
die "\n";
}
# Adds money / player id into hash
# Two arguments - key, amount of money, and (to / from)
sub put_into
{
my ($key, $amt, $tim, $tf) = @_;
$tf = ($tf * 3);
$$money_hash{$key} = [0, 0, 0, 0, 0, 0, 0] if(!exists $$money_hash{$key});
$$money_hash{$key}->[$tf] += 1;
$$money_hash{$key}->[$tf+1] += $amt;
$$money_hash{$key}->[$tf+2] = $tim if($tim gt $$money_hash{$key}->[$tf+2]);
}
# Will sort numbers and strings - returns -1, 0, or 1
# Takes two arguments, to compare
sub str_num_cmp
{
my($a, $b) = @_;
# Both are numbers
return $a <=> $b if($a =~ /^\d+$/ && $b =~ /^\d+$/);
# Both are not numbers
return $a cmp $b if(!($a =~ /^\d+$/) && !($b =~ /^\d+$/));
# $a is a number, $b is not
return 1 if($a =~ /^\d+$/);
# $a is not a number, $ b is
return -1;
}
# Displays the money chart in %money_hash
# Takes no arguments
sub display_money_chart
{
my $temp_total = $big_zero;
my $temp_hash = $_[0];
my @key_vals;
my @sorted_vals;
@key_vals = keys %$money_hash;
@sorted_vals = ();
foreach my $sub_elem (@key_vals)
{
push(@sorted_vals, [$sub_elem, $$money_hash{$sub_elem}->[0], $$money_hash{$sub_elem}->[1],
$$money_hash{$sub_elem}->[2], $$money_hash{$sub_elem}->[3],
$$money_hash{$sub_elem}->[4], $$money_hash{$sub_elem}->[5]]);
}
@sorted_vals = sort { &str_num_cmp($b->[$sort_val], $a->[$sort_val]) } @sorted_vals;
@sorted_vals = reverse(@sorted_vals) if($sort_val == 0);
foreach my $val (@sorted_vals)
{
if((!exists $args{"m"} || (&str_num_cmp($val->[$sort_val], $min_thresh) == 0 || &str_num_cmp($val->[$sort_val], $min_thresh) == 1))
&& (!exists $args{"x"} || (&str_num_cmp($val->[$sort_val], $max_thresh) == 0 || &str_num_cmp($val->[$sort_val], $max_thresh) == -1))
&& (!exists $args{"e"} || &str_num_cmp($val->[$sort_val], $max_thresh) == 0))
{
$total_in += $val->[5];
$total_out += $val->[2];
$num_total_in += $val->[4];
$num_total_out += $val->[1];
if(!$abridged)
{
printf "\t%-34s%-8s%-12s%-24s%-8s%-12s%-24s\n", $val->[0], $val->[1], $val->[2], $val->[3], $val->[4], $val->[5], $val->[6];
}
else
{
$str_out = sprintf "%s\t%s\t%s\t%s\t%s\t%s\n", $val->[5], $val->[4], $val->[2], $val->[1], ($val->[5] - $val->[2]), $val->[0];
$str_out =~ s/\+//g;
print $str_out;
}
}
}
}
$start_time = time;
&usage() if(!getopts('dpnatNATm:x:l:e:s:S:f:', \%args));
&usage if(((exists $args{"n"}) + (exists $args{"a"}) + (exists $args{"t"})
+ (exists $args{"N"}) + (exists $args{"A"}) + (exists $args{"T"}) + (exists $args{"p"})) > 1);
&usage if((exists $args{"e"}) && (exists $args{"m"} || exists $args{"x"}));
# Process arguments
$sort_val = 0 if(exists $args{"p"});
$sort_val = 1 if(exists $args{"n"});
$sort_val = 2 if(exists $args{"a"});
$sort_val = 3 if(exists $args{"t"});
$sort_val = 4 if(exists $args{"N"});
$sort_val = 5 if(exists $args{"A"});
$sort_val = 6 if(exists $args{"T"});
$max_cnt = $args{"l"} if(exists($args{"l"}));
$min_thresh = $args{"m"} if(exists($args{"m"}));
$max_thresh = $args{"x"} if(exists($args{"x"}));
$min_thresh = $max_thresh = $args{"e"} if(exists($args{"e"}));
$start_date = $args{"s"} if(exists($args{"s"}));
$end_date = $args{"S"} if(exists($args{"S"}));
$abridged = 0 if(exists($args{"d"}));
if(exists($args{"f"}))
{
&usage if(@ARGV < 1);
open (MONEY, $args{"f"});
}
else
{
&usage if(@ARGV < 4);
my $server = shift;
my $start = shift;
my $end = shift;
open(MONEY, "/m2/logsrv/log_dump.pl swg money $server $start $end |");
}
# Fill the player hash
foreach(@ARGV)
{
$player_hash{$_} = {};
}
while (<MONEY>)
{
# Clear out three possible Unicode chars
s/^...20(\d{2})/20$1/;
chomp;
my $day;
my $time;
my $planet;
my $vara;
my $varb;
my $varc;
my $type;
my $from;
my $to;
my $amount;
my $total;
# Check start date if argument was passed
if(exists $args{"s"} && /^(\S+)\s+(\S+)/)
{
my $date = $1." ".$2;
next if($date lt $start_date);
}
# Check end date if argument was passed
if(exists $args{"S"} && /^(\S+)\s+(\S+)/)
{
my $date = $1." ".$2;
last if($date gt $end_date);
}
# Check a few special cases
if(/^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+) (from|to) bank by (.+), amount (\d+), (total|total\(from\)) -?(\d+):$/)
{
#player deposited / withdrew money from bank
$day = $1;
$time = $2;
$planet = $3;
$vara = $4;
$varb = $5;
$varc = $6;
$type = $7;
$from = $8;
$to = $9;
$amount = $10;
$total = $11;
#Strip the station id - can cause problems searching for player id
$from =~ s/StationId\(\d+\)//g;
$to =~ s/StationId\(\d+\)//g;
# If it's a named account, strip the name out
$to =~ s/named account //;
# Extract player Id number
$to =~ s/.*\((\d+)\).*/$1/ if($to =~ /Player/);
# Add into the approproiate hash
if($from eq "to" && exists $player_hash{$to})
{
$money_hash = $player_hash{$to};
&put_into("bank", $amount, ($day." ".$time), 0);
}
if($to eq "from" && exists $player_hash{$to})
{
$money_hash = $player_hash{$to};
&put_into("bank", $amount, ($day." ".$time), 1);
}
}
elsif(/logging out with/ || /logged in with/)
{
#player logged in / out
next;
}
elsif(/^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+) from (.+) to (.+), amount (\d+), (total|total\(from\)) -?(\d+):$/)
{
$day = $1;
$time = $2;
$planet = $3;
$vara = $4;
$varb = $5;
$varc = $6;
$type = $7;
$from = $8;
$to = $9;
$amount = $10;
$total = $11;
#Strip the station id - can cause problems searching for player id
$from =~ s/StationId\(\d+\)//g;
$to =~ s/StationId\(\d+\)//g;
# If it's a named account, strip the name out
$from =~ s/named account //;
$to =~ s/named account //;
# Extract player Id number
$from =~ s/.*\((\d+)\).*/$1/ if($from =~ /Player/);
$to =~ s/.*\((\d+)\).*/$1/ if($to =~ /Player/);
# Special case where player has " from " in store title
if($type =~ /Player/)
{
$type =~ s/(.*) from /$1/;
$from =~ s/.*\((\d+)\).*/$1/;
}
# Add into the approproiate hash
if(exists $player_hash{$from})
{
$money_hash = $player_hash{$from};
&put_into($to, $amount, ($day." ".$time), 0);
}
if(exists $player_hash{$to})
{
$money_hash = $player_hash{$to};
&put_into($from, $amount, ($day." ".$time), 1);
}
}
else
{
print "$_\n";
die "Error in log file format.\n";
}
# Check counter
++$cnt;
last if($cnt == $max_cnt);
}
close (MONEY);
#update money hash
foreach my $player (keys %player_hash)
{
$money_hash = $player_hash{$player};
$total_in = $big_zero;
$total_out = $big_zero;
$num_total_in = $big_zero;
$num_total_out = $big_zero;
if(!$abridged)
{
print "Transactions for user $player_id:\n";
print "---------------------------------\n\n";
print "\tTransactions:\n";
printf "\t%-34s%-8s%-12s%-24s%-8s%-12s%-24s\n", "Player Id:", "# To:", "Amt To:", "Last Tm To", "# Fr:", "Amt Fr:", "Last Tm Fr";
printf "\t%-34s%-8s%-12s%-24s%-8s%-12s%-24s\n", "----------", "-----", "-------", "----------", "-----", "-------", "----------";
display_money_chart();
print "\n";
print "Total money given to $player_id: $total_in\n";
print "Total money $player_id gave: $total_out\n";
print "\nFinished in ".(time - $start_time)." seconds.\n";
}
else
{
print "Information for player id: $player\n";
printf "%s\t%s\t%s\t%s\t%s\t%s\n", "To:", "# To:", "From:", "# From", "Delta:", "Account:";
display_money_chart();
$str_out = sprintf "\n%s\t%s\t%s\t%s\t%s\t%s\n", $total_in, $num_total_in, $total_out, $num_total_out, ($total_in - $total_out), "Total";
$str_out =~ s/\+//g;
print $str_out;
}
print "\n";
}

View File

@@ -0,0 +1,339 @@
#! /usr/bin/perl
use strict;
use warnings;
use Getopt::Std;
use Math::BigInt;
my %from_hash;
my %to_hash;
my $cnt = 0;
my $sort_val = 0;
my $max_cnt = 0;
my %args;
my $start_time;
my $min_thresh = 0;
my $max_thresh = 0;
my $start_date;
my $end_date;
my $total_in = new Math::BigInt '0';
my $total_out = new Math::BigInt '0';
my $num_total_in = new Math::BigInt '0';
my $num_total_out = new Math::BigInt '0';
my $temp_out = new Math::BigInt '0';
my $temp_in = new Math::BigInt '0';
my $num_temp_out = new Math::BigInt '0';
my $num_temp_in = new Math::BigInt '0';
my $big_zero = new Math::BigInt '0';
my $str_out;
my $abridged = 1;
my @keys;
# Usage
sub usage
{
my $name = $0;
$name =~ s/^(.*)\\//;
print STDERR "\nUsage:\n";
print STDERR "\t$name <optional parameters> <server> <start date> <end date>\n";
print STDERR "\t\tDate format = yyyy-mm-dd (eg: 2004-06-08)\n";
print STDERR "\t$name <optional parameters> -f <money log file>\n\n";
print STDERR "Optional parameters:\n";
print STDERR "\t[-l <num>] [-s <time> | -S <time>] [-p | -n | -a] [-m <num> | -x <num> | -e <num>] [-d]\n";
print STDERR "\t-l <num>\tOnly process <num> lines of log file\n";
print STDERR "\t-s <time>\tStart processing at <time> \(eg \"2004-06-01 17:00:03\"\)\n";
print STDERR "\t-S <time>\tEnd processing at <time>\n";
print STDERR "\t-p \tSort results by player id number (default)\n";
print STDERR "\t-n \tSort results by number of transactions\n";
print STDERR "\t-a \tSort results by total amount of money changed\n";
print STDERR "\t-t \tSort results by time of most recent transaction\n";
print STDERR "\t-m <num>\tSet minimum threshold for sorted parameter\n";
print STDERR "\t-x <num>\tSet maximum threshold for sorted parameter\n";
print STDERR "\t-e <num>\tSet threshold to exactly <num>\n";
print STDERR "\t-d \tShow detailed output\n";
die "\n";
}
# Adds money / player id into hash
# Three arguments - key, value, amount of money, and which hash (to / from)
sub put_into
{
my %head;
my ($key, $val, $amt, $tim, $tf) = @_;
%head = ($tf ? %to_hash : %from_hash);
$head{$key} = {} if(!exists $head{$key});
$head{$key}->{$val} = [0, 0, 0] if(!exists $head{$key}->{$val});
$head{$key}->{$val}->[0] += 1;
$head{$key}->{$val}->[1] += $amt;
$head{$key}->{$val}->[2] = $tim if($tim gt $head{$key}->{$val}->[2]);
if($tf) { %to_hash = %head; }
else { %from_hash = %head; }
}
# Will sort numbers and strings - returns -1, 0, or 1
# Takes two arguments, to compare
sub str_num_cmp
{
my($a, $b) = @_;
# Both are numbers
return $a <=> $b if($a =~ /^\d+$/ && $b =~ /^\d+$/);
# Both are not numbers
return $a cmp $b if(!($a =~ /^\d+$/) && !($b =~ /^\d+$/));
# $a is a number, $b is not
return 1 if($a =~ /^\d+$/);
# $a is not a number, $ b is
return -1;
}
sub display_money_chart {
my $temp_total = new Math::BigInt '0';
my $temp_num = new Math::BigInt '0';
my $temp_hash = $_[0];
my $t_out = $_[1];
my @inner_keys;
my @sorted_vals;
@inner_keys = keys %$temp_hash;
@inner_keys = sort @inner_keys;
@sorted_vals = ();
foreach my $sub_elem (@inner_keys)
{
push(@sorted_vals, [$sub_elem, %$temp_hash->{$sub_elem}->[0], %$temp_hash->{$sub_elem}->[1], %$temp_hash->{$sub_elem}->[2]]);
}
@sorted_vals = sort { &str_num_cmp($b->[$sort_val], $a->[$sort_val]) } @sorted_vals;
@sorted_vals = reverse(@sorted_vals) if($sort_val == 0);
foreach my $val (@sorted_vals)
{
if((!exists $args{"m"} || (&str_num_cmp($val->[$sort_val], $min_thresh) == 0 || &str_num_cmp($val->[$sort_val], $min_thresh) == 1))
&& (!exists $args{"x"} || (&str_num_cmp($val->[$sort_val], $max_thresh) == 0 || &str_num_cmp($val->[$sort_val], $max_thresh) == -1))
&& (!exists $args{"e"} || &str_num_cmp($val->[$sort_val], $max_thresh) == 0))
{
if($t_out)
{
$total_out += $val->[2];
$num_total_out += $val->[1];
}
else
{
$total_in += $val->[2];
$num_total_in += $val->[1];
}
$temp_total += $val->[2];
$temp_num += $val->[1];
if(!$abridged)
{
printf "\t\t%-32s%-10d%-12d%-24s\n", $val->[0], $val->[1], $val->[2], $val->[3];
}
}
}
return ($temp_total, $temp_num);
}
$start_time = time;
&usage() if(!getopts('dpnatm:x:l:e:s:S:f:', \%args));
&usage if(((exists $args{"p"}) + (exists $args{"n"}) + (exists $args{"a"})) > 1);
&usage if((exists $args{"e"}) && (exists $args{"m"} || exists $args{"x"}));
# Process arguments
$sort_val = 0 if(exists $args{"p"});
$sort_val = 1 if(exists $args{"n"});
$sort_val = 2 if(exists $args{"a"});
$sort_val = 3 if(exists $args{"t"});
$max_cnt = $args{"l"} if(exists($args{"l"}));
$min_thresh = $args{"m"} if(exists($args{"m"}));
$max_thresh = $args{"x"} if(exists($args{"x"}));
$min_thresh = $max_thresh = $args{"e"} if(exists($args{"e"}));
$start_date = $args{"s"} if(exists($args{"s"}));
$end_date = $args{"S"} if(exists($args{"S"}));
$abridged = 0 if(exists($args{"d"}));
if(exists($args{"f"}))
{
&usage if(@ARGV != 0);
open (MONEY, $args{"f"});
}
else
{
&usage if(@ARGV != 3);
open(MONEY, "/m2/logsrv/log_dump.pl swg money $ARGV[0] $ARGV[1] $ARGV[2] |");
}
while (<MONEY>)
{
# Clear out three possible Unicode chars
s/^...20(\d{2})/20$1/;
chomp;
# Check start date if argument was passed
if(exists $args{"s"} && /^(\S+)\s+(\S+)/)
{
my $date = $1." ".$2;
next if($date lt $start_date);
}
# Check end date if argument was passed
if(exists $args{"S"} && /^(\S+)\s+(\S+)/)
{
my $date = $1." ".$2;
last if($date gt $end_date);
}
# Check a few special cases
if(/cash withdraw from bank by/ || /cash deposit to bank/)
{
#player deposited / withdrew money from bank
}
elsif(/logging out with/ || /logged in with/)
{
#player logged in / out
}
elsif(/^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+) from (.+) to (.+), amount (\d+), (total|total\(from\)) -?(\d+):$/)
{
my $day = $1;
my $time = $2;
my $planet = $3;
my $vara = $4;
my $varb = $5;
my $varc = $6;
my $type = $7;
my $from = $8;
my $to = $9;
my $amount = $10;
my $total = $11;
my $from_named = $from =~ s/named account //;
my $to_named = $to =~ s/named account //;
#Strip the station id - can cause problems searching for player id
$from =~ s/StationId\(\d+\)//g;
$to =~ s/StationId\(\d+\)//g;
# Extract player Id number
$from =~ s/.*\((\d+)\).*/$1/ if($from =~ /Player/);
$to =~ s/.*\((\d+)\).*/$1/ if($to =~ /Player/);
# Special case where player has " from " in store title
if($type =~ /Player/)
{
$type =~ s/(.*) from /$1/;
$from =~ s/.*\((\d+)\).*/$1/;
}
# Add into the approproiate hash
if($from_named)
{
&put_into($from, $to, $amount, ($day." ".$time), 0);
}
if($to_named)
{
&put_into($to, $from, $amount, ($day." ".$time), 1);
}
}
else
{
print "$_\n";
die "Error in log file format.\n";
}
# Check counter
++$cnt;
last if($cnt == $max_cnt);
}
close (MONEY);
print "Named users transaction information:\n" if (!$abridged);
print "------------------------------------\n\n" if (!$abridged);
@keys = keys %from_hash;
push (@keys, (keys %to_hash));
@keys = sort @keys;
my $prev = -1;
@keys = grep($_ ne $prev && ($prev = $_), @keys);
printf "%s\t%s\t%s\t%s\t%s\t%s\n", "To:", "# To:", "From:", "# From:", "Delta:", "Account:" if($abridged);
foreach my $elem (@keys)
{
$temp_in = $big_zero;
$temp_out = $big_zero;
$num_temp_in = $big_zero;
$num_temp_out = $big_zero;
print "$elem:\n" if(!$abridged);
if(exists $from_hash{$elem})
{
if(!$abridged)
{
print "\tMoney from $elem:\n";
printf "\t\t%-32s%-10s%-12s%-24s\n", "To:", "# Times:", "Total Amt:", "Most Recent Time:";
printf "\t\t%-32s%-10s%-12s%-24s\n", "---", "--------", "----------", "-----------------";
}
($temp_out, $num_temp_out) = display_money_chart($from_hash{$elem}, 0);
if(!$abridged)
{
print "\tTotal $elem gave:\n";
print "\t\t$temp_out\n\n";
}
}
if(exists $to_hash{$elem})
{
if(!$abridged)
{
print "\tMoney to $elem:\n";
printf "\t\t%-32s%-10s%-12s%-24s\n", "From:", "# Times:", "Total Amt:", "Most Recent Time:";
printf "\t\t%-32s%-10s%-12s%-24s\n", "-----", "--------", "----------", "-----------------";
}
($temp_in, $num_temp_in) = display_money_chart($to_hash{$elem}, 1);
if(!$abridged)
{
print "\tTotal given to $elem:\n";
print "\t\t$temp_in\n\n";
}
}
printf "%s\t%s\t%s\t%s\t%s\t%s\n", "To:", "# To:", "From:", "# From:", "Delta:", "Account:" if(!$abridged);
$str_out = sprintf "%s\t%s\t%s\t%s\t%s\t%s\n", $temp_in, $num_temp_in, $temp_out, $num_temp_out, ($temp_out - $temp_in), $elem;
$str_out =~ s/\+//g;
print $str_out;
}
if(!$abridged)
{
print "\nTotal out:\t$total_out\n";
print "Total in:\t$total_in\n";
print "Total Delta:\t".($total_in - $total_out)."\n";
print "\nFinished in ".(time - $start_time)." seconds.\n";
}
else
{
$str_out = sprintf "\n%s\t%s\t%s\t%s\t%s\t%s\n", $total_out, $num_total_out, $total_in, $num_total_in, ($total_in - $total_out), "Total";
$str_out =~ s/\+//g;
print $str_out;
}

View File

@@ -0,0 +1,174 @@
#!/usr/bin/perl -i
use XML::Parser::PerlSAX;
die "usage: NormalizeExcelXml.pl <filename>\n" unless (@ARGV == 1);
$filename = $ARGV[0];
die "$filename not found\n" unless (-e $filename);
die "$filename not writable\n" unless (-w $filename);
$backup = $filename . "~";
die "Could not rename $filename -> $backup\n" unless (rename ($filename, $backup));
open (INFILE, "<$backup");
open (OUTFILE, ">$filename");
select(OUTFILE);
my $handler = MyHandler->new();
my $parser = XML::Parser::PerlSAX->new( Handler => $handler );
print "<?xml version=\"1.0\"?>";
$parser->parse(Source => { ByteStream => \*INFILE });
package MyHandler;
sub new {
my ($type) = @_;
my $self = {};
$quiet_level = 0;
$opened = 0;
$indent_level = "";
$open_tag = "";
$in_cell = 0;
%bad_elements =
(
"NamedCell", 1,
"Styles", 1,
);
%bad_attributes =
(
"ss:StyleID", 1,
"ss:AutoFitWidth", 1,
);
return bless ($self, $type);
}
sub start_element
{
my ($self, $element) = @_;
my $name = $element->{Name};
if (exists $bad_elements{$name})
{
$quiet_level += 1;
}
if ($quiet_level == 0)
{
if (!$open_tag eq "")
{
print ">";
}
if (! $in_cell )
{
print "\n$indent_level";
}
print "<$name";
foreach $z (keys %{$element->{Attributes}})
{
if (!exists $bad_attributes{$z})
{
print " " . $z . '="';
$_ = $element->{Attributes}->{$z};
s/\"/&quot;/g;
s/</&lt;/g;
s/>/&gt;/g;
print $_;
print '"';
}
}
$open_tag = $name;
#$indent_level = $indent_level . ' ';
$opened = 1;
if ($name eq "Cell")
{
$in_cell = 1;
}
}
}
sub end_element {
my ($self, $element) = @_;
my $name = $element->{Name};
if ($quiet_level == 0)
{
#chop $indent_level;
if ($open_tag eq $name)
{
print "/>";
}
else
{
if (!$opened && !$in_cell)
{
print "\n$indent_level";
}
print "</$name>";
}
$open_tag = "";
$opened = 0;
}
if ($name eq "Cell")
{
$in_cell = 0;
}
if (exists $bad_elements{$name})
{
$quiet_level -= 1;
}
}
sub characters {
my ($self, $characters) = @_;
$_ = $characters->{Data};
chomp;
if (/\S/)
{
s/\"/&quot;/g;
s/</&lt;/g;
s/>/&gt;/g;
if (!$open_tag eq "")
{
print ">";
$open_tag = "";
}
print $_;
}
}

View File

@@ -0,0 +1,144 @@
#! /usr/bin/perl
# ======================================================================
# ======================================================================
use strict;
use warnings;
# ======================================================================
# Globals
# ======================================================================
my %str_to_tags;
my %str_to_files;
my $tmprsp = "a.rsp";
my $name = $0;
$name =~ s/^(.*)\\//;
# ======================================================================
# Subroutines
# ======================================================================
sub usage
{
die "\nTool used to scan through conversation scripts and verify that all .stf files have the appropriate tags\n\n".
"\tUsage\n".
"\t\t$name <script file>\n\n";
}
sub testfile
{
#p4 fstat //depot/swg/current/data/.../string/en/bartender.stf
#echo c:\work\swg\current\data\sku.0\sys.server\built\game\string\en\bartender.stf > a.rsp
#WordCountTool.exe -d a.rsp
my $file = shift @_;
my $path = $file;
$path =~ s/\./\//g;
my @files;
open(P4, "p4 fstat //depot/swg/current/data/.../string/en/${path}.stf | ") or die "Cannot open file: $path\n";
while(<P4>)
{
push @files, $1 if(/^\.\.\. clientFile (.+)$/);
}
close(P4);
foreach my $elem (@files)
{
print "\t$elem:\n";
my %filetags;
system("echo $elem > $tmprsp");
open(WORDCOUNT, "WordCountTool.exe -d $tmprsp | ");
while(<WORDCOUNT>)
{
$filetags{"\"$1\""} = 0 if(/^\t(\S+)\t/);
}
close(WORDCOUNT);
my $ref = $str_to_tags{$file};
my $missing = 0;
foreach my $tag (sort keys %$ref)
{
if(!exists $filetags{$tag})
{
print "\t\tis missing $tag\n";
$missing = 1;
}
}
$missing ? print "\n" : print "\t\tNone missing\n\n";
}
unlink($tmprsp);
}
# ======================================================================
# Main
# ======================================================================
&usage() if(@ARGV != 1);
my $scriptfile = shift;
print "Scanning script file...\n";
open(SCRIPT, "<$scriptfile");
while(<SCRIPT>)
{
$str_to_files{$2} = $3 if(/(const)?\s+string\s+([A-Za-z_]+)\s+=\s+"([A-Za-z_\.]+)"/);
#if(/(new)?\s+string_id\s*\(\s*([A-Za-z_]+)\s*,\s*"([A-Za-z_]+)"\s*\)/)
if(/(new)?\s+string_id\s*\(\s*([A-Za-z_]+)\s*,\s*(.+)\s*\)/)
{
my $string = $2;
my $tagline = $3;
$str_to_tags{$str_to_files{$string}} = {} if(!exists $str_to_tags{$str_to_files{$string}});
if($tagline =~ s/"(.+)"\s*\+\s*rand\s*\(\s*(\d)+\s*,\s*(\d)+\s*\)//)
{
my $tagline = $1;
my $num = $2;
my $end = $3;
while($num <= $end)
{
$str_to_tags{$str_to_files{$string}}->{"\"${tagline}$num\""} = 0;
++$num;
}
}
else
{
$tagline =~ s/\)//g;
$str_to_tags{$str_to_files{$string}}->{$tagline} = 0;
}
}
}
close(SCRIPT);
foreach my $str (sort keys %str_to_tags)
{
my $hash_ref = $str_to_tags{$str};
print "\nFile: '$str' needs to contain\n";
foreach my $tag (sort keys %$hash_ref)
{
print "\t$tag\n";
}
}
print "\nScanning for missing elements of script files...\n";
foreach my $filename (sort keys %str_to_tags)
{
testfile($filename);
}

View File

@@ -0,0 +1,43 @@
#!/usr/bin/perl -w
use BuildFunctions;
###
# Copyright (C)2000-2002 Sony Online Entertainment Inc.
# All Rights Reserved
#
# Title: SwgClientClean.pl
# Description: Build release and debug SWGGameServer. Emails the resulting log files to gmcdaniel.
# @author $Author: gmcdaniel $
# @version $Revision: #3 $
##
########## MAIN ##########
##
# Delete compile directory for clean build
system("c:\\4nt302\\4nt /c del /s /y ..\\src\\compile");
#
## End of Delete compile directory for clean build
##
# Build Projects and Check for Errors
build_project ("SwgClient");
Check_For_Warnings_and_Errors("SwgClient","SwgClient.exe");
#
## End of Build Projects and Check for Errors
########## END OF MAIN ##########

View File

@@ -0,0 +1,44 @@
#!/usr/bin/perl -w
use BuildFunctions;
###
# Copyright (C)2000-2002 Sony Online Entertainment Inc.
# All Rights Reserved
#
# Title: SwgGameServerClean.pl
# Description: Build release and debug SWGGameServer. Emails the resulting log files to gmcdaniel.
# @author $Author: gmcdaniel $
# @version $Revision: #3 $
##
########## MAIN ##########
##
# Delete compile directory for clean build
system("c:\\4nt302\\4nt /c del /s /y ..\\src\\compile");
#
## End of Delete compile directory for clean build
##
# Build Projects and Check for Errors
build_project ("SwgGameServer");
Check_For_Warnings_and_Errors("SwgGameServer","SwgGameServer.exe");
#
## End of Build Projects and Check for Errors
########## END OF MAIN ##########

View File

@@ -0,0 +1,48 @@
#!/usr/bin/perl -w
use BuildFunctions;
###
# Copyright (C)2000-2002 Sony Online Entertainment Inc.
# All Rights Reserved
#
# Title: SwgGodClientClean.pl
# Description: Build release and debug SWGGameServer. Emails the resulting log files to gmcdaniel.
# @author $Author: gmcdaniel $
# @version $Revision: #3 $
##
########## MAIN ##########
##
# Delete compile directory for clean build
system("c:\\4nt302\\4nt /c del /s /y ..\\src\\compile");
#
## End of Delete compile directory for clean build
##
# Build Projects and Check for Errors
build_project ("SwgGodClient");
Check_For_Warnings_and_Errors("SwgGodClient","SwgGodClient.exe");
#
## End of Build Projects and Check for Errors
########## END OF MAIN ##########

View File

@@ -0,0 +1,46 @@
#!/usr/bin/perl -w
use BuildFunctions;
###
# Copyright (C)2000-2002 Sony Online Entertainment Inc.
# All Rights Reserved
#
# Title: allClientBuildClean.pl
# Description: Builds all_Client debug and release and sends log files to gmcdaniel
# @author $Author: gmcdaniel $
# @version $Revision: #3 $
###
########## MAIN ##########
##
# Delete compile directory for clean build
system("c:\\4nt302\\4nt /c del /s /y ..\\src\\compile");
#
## End of Delete compile directory for clean build
##
# Build Projects and Check for Errors
build_project ("_all_client");
Check_For_Warnings_and_Errors("_all_client","_all_client");
#
## End of Build Projects and Check for Errors
########## END OF MAIN ##########

View File

@@ -0,0 +1,147 @@
#!/perl/bin
die "usage: perl assignVertexShaderConstants.pl input_template hlsl.inc dx.inc shaderBuilder.inc\n" if (@ARGV != 4);
my $register = 0;
# define the sizes of some intrinsic types
my %size;
$size{"float"} = 1;
$size{"float2"} = 1;
$size{"float3"} = 1;
$size{"float4"} = 1;
$size{"float4x4"} = 4;
# open all the files
open(INPUT, shift);
open(HLSL, ">".shift);
open(CPP, ">".shift);
open(SB, ">".shift);
while (<INPUT>)
{
chomp;
if (/^struct/)
{
# begin recording information about a struct
print HLSL "$_\n";
s/^struct\s+//;
$struct = $_;
}
elsif ($struct ne "" && /^};/ )
{
# end recording information about a struct
print HLSL "$_\n";
undef $struct;
}
elsif (/^\/\// || /^#pragma/ || /^{/ || /^\s*$/)
{
# copy any comments, pragmas, open curly braces, or blank lines
print HLSL "$_\n";
}
elsif (/^static const int /)
{
# record global integer values for array sizes
print HLSL "$_\n";
s/^static const int //;
s/;//;
s/=//;
($variable, $value) = split;
$variable{$variable} = $value;
}
else
{
# assume this is a global variable or structure member
s/;//;
my $array = 0;
my $count = 1;
if (/\[(.+)\]/)
{
if (defined $variable{$1})
{
$count = $variable{$1};
}
else
{
$count = $1;
}
$array = 1;
}
($type, $variable) = split;
die "unknown size for $type\n" if (!defined $size{$type});
if (defined $struct)
{
print HLSL "$_;\n";
$size{$struct} += $size{$type} * $count;
@array = ( "" );
@array = (0 .. $count-1) if ($array);
$variable =~ s/\[.*//;
foreach $index (@array)
{
# handle structure members
$index = "[$index]" if ($index ne "");
if (defined $members{$type})
{
my @members = split (/\s+/, $members{$type});
while (@members)
{
my $member = shift @members;
my $size = shift @members;
$members{$struct} .= " " if (defined $members{$struct});
$members{$struct} .= "$variable$index.$member $size";
}
}
else
{
$members{$struct} .= " " if (defined $members{$struct});
$members{$struct} .= "$variable$index $size{$type}";
}
}
}
else
{
# handle global variables
s/;//;
if (defined $members{$type})
{
# emit registers for all the stucture members
my $offset = 0;
my @members = split (/\s+/, $members{$type});
while (@members)
{
my $member = shift @members;
print SB "\t\taddConstantRegister(\"$variable.$member\", ", $register + $offset, ");\n";
$offset += shift @members;
}
}
else
{
# emit register for the variable
print SB "\t\taddConstantRegister(\"$variable\", $register);\n";
}
print CPP "\tVSCR_$variable = $register,\n";
print HLSL "$_ : register(c$register);\n";
$register += $size{$type} * $count;
}
}
}
print CPP "\tVSCR_MAX", " = $register\n";
close(INPUT);
close(HLSL);
close(CPP);
close(SB);

View File

@@ -0,0 +1,40 @@
use POSIX ":sys_wait_h";
use FindBin '$Bin';
require "$Bin/taskmanager.pl";
require "$Bin/centralserver.pl";
require "$Bin/passfail.pl";
require "$Bin/loginserver.pl";
require "$Bin/databaseserver.pl";
require "$Bin/planetserver.pl";
$target = $ARGV[0];
my $testPlanet = "tatooine";
if($target eq "")
{
fail("target (debug or release) not specified in test script\n");
}
#taskmanagerStartupShutdown($target);
#centralServerStartupShutdown($target);
loginServerStartup($target);
clusterStartup($target);
centralServerRunning($target);
databaseServerConnectedToCentralServer($target);
databaseServerRunning($target);
planetServerConnected($target);
hasPlanetServer($target, $testPlanet);
planetServerRunning($target, $testPlanet);
# gameServerRunning($target);
# chatServerRunning($target);
# commoditiesServerRunning($target);
# connectionServerRunning($target);
# customerServiceServerRunning($target);
# logServerRunning($target);
# metricsServerRunning($target);
# transferServerRunning($target);
# clusterIsReady($target);
loginServerShutdown($target);
clusterShutdown($target);

View File

@@ -0,0 +1,98 @@
use POSIX ":sys_wait_h";
use FindBin '$Bin';
require "$Bin/passfail.pl";
sub backgroundProcess
{
my($prefix, $program, $timeout, $funcPtr) = @_;
$cmd = "$prefix/$program";
$childId = fork();
if($childId == 0)
{
$result = system("$cmd");
exit($result);
}
else
{
$runTime = time();
do
{
$elapsed = time() - $runTime;
if($elapsed > $timeout)
{
kill(11, $childId);
chomp($cwd = `pwd`);
fail("$cmd did not exit in time. Sending SIGSEGV to force a core dump in $cwd");
}
if(defined($funcPtr))
{
&$funcPtr();
}
$kid = waitpid($childId, WNOHANG);
} until $kid > 0 ;
$taskResult = $?;
if($taskResult != 0)
{
fail("$cmd did not exit cleanly!!");
}
}
return 1;
}
sub startBackgroundProcess
{
my($prefix, $program, $timeout, $funcPtr) = @_;
$cmd = "$prefix/$program";
$childId = fork();
if($childId == 0)
{
$result = system("$cmd");
exit($result);
}
else
{
$runTime = time();
do
{
$elapsed = time() - $runTime;
if($elapsed > $timeout)
{
kill(11, $childId);
chomp($cwd = `pwd`);
fail("$cmd did not respond to run query in time. Sending SIGSEGV to force core dump in $cwd");
}
$functionResult = 0;
if(defined($funcPtr))
{
$functionResult = &$funcPtr();
}
else
{
$functionResult = 1;
}
$kid = waitpid($childId, WNOHANG);
} until $kid > 0 || $functionResult != 0;
$taskResult = $?;
if(defined($funcPtr))
{
if($functionResult == -1)
{
fail("run query function for $cmd returned -1. Failed to start background process.");
}
}
elsif($kid > 0 && $taskResult != 0)
{
fail("$cmd failed to start properly");
}
}
return $childId;
}
1;

View File

@@ -0,0 +1,45 @@
use FindBin '$Bin';
require "$Bin/passfail.pl";
require "$Bin/background_process.pl";
sub centralServerStartupShutdown
{
$passFailMessage = "CentralServer startup and shutdown";
my($prefix) = @_;
failOnFalse(backgroundProcess($prefix, "CentralServer -- -s CentralServer shutdown=true 2>/dev/null", 10), $passFailMessage, $passFailMessage);
}
sub centralServerRunning
{
my($prefix) = @_;
my $result = runCommand($prefix, "runState");
my $testMessage = "CentralServer running";
failOnFalse($result eq "running", $testMessage, $testMessage);
}
sub databaseServerConnectedToCentralServer
{
my($prefix) = @_;
my $result = "";
my $passFailMessage = "DatabaseServer connected to CentralServer";
# test that the database server has connected to the
# central server by querying Central for a db connection.
# poll CentralServer repeatedly until it responds with a "1"
# or more than 10 seconds has passed
failOnFalse(runCommandUntil($prefix, "dbconnected", "1", 10), $passFailMessage, $passFailMessage);
}
sub planetServerConnected
{
my($prefix) = @_;
my $passFailMessage = "PlanetServer connected to CentralServer";
failOnFalse(runCommandUntil($prefix, "getPlanetServersCount", "1", 10, sub { $_[0] > 0; }), $passFailMessage, $passFailMessage);
}
sub hasPlanetServer
{
my($prefix, $planetName) = @_;
my $passFailMessage = "PlanetServer for $planetName is connected to CentralServer";
failOnFalse(runCommandUntil($prefix, "hasPlanetServer $planetName", "1", 10), $passFailMessage, $passFailMessage);
}

View File

@@ -0,0 +1,13 @@
use FindBin '$Bin';
require "$Bin/passfail.pl";
require "$Bin/background_process.pl";
sub databaseServerRunning
{
my($prefix) = @_;
my $result = runCommand($prefix, "database runState");
my $testMessage = "DatabaseServer reports a true run state";
failOnFalse($result eq "running", $testMessage, $testMessage);
}
1;

View File

@@ -0,0 +1,55 @@
use FindBin '$Bin';
require "$Bin/passfail.pl";
require "$Bin/background_process.pl";
$loginServerPid = 0;
sub loginServerStartup
{
$passFailMessage = "LoginServer startup";
my($prefix) = @_;
# determin the user id
$uid = getpwuid($<);
my $branch = "";
#determing the branch
@dirs = split('/', $Bin);
$x = 0;
for $i(@dirs)
{
if($i eq "swg")
{
if(@dirs[$x+2] eq "tools")
{
$branch = @dirs[$x+1];
break;
}
}
$x++;
}
$dbuid = "$uid\_$branch";
$loginServerPid = startBackgroundProcess($prefix, "LoginServer -- -s LoginServer databaseProtocol=OCI DSN=swodb databaseUID=$dbuid databasePWD=changeme 2>/dev/null", 10);
failOnFalse($loginServerPid, $passFailMessage, $passFailMessage);
}
sub loginServerShutdown
{
if($loginServerPid != 0)
{
$kid = 0;
do
{
$kid = waitpid($loginServerPid, WNOHANG);
if($kid == 0)
{
system("echo \"login exit\" | debug/ServerConsole -- -s ServerConsole > /dev/null");
}
} until $kid > 0;
failOnFalse($? == 0, "LoginServer shutdown", "LoginServer shutdown");
}
}
1;

View File

@@ -0,0 +1,28 @@
sub pass
{
my ($message) = @_;
print "PASS: $message\n";
}
sub fail
{
my ($message) = @_;
print "FAIL: $message\n";
exit(1);
}
sub failOnFalse
{
my ($result, $failMessage, $passMessage) = @_;
if($result == 0)
{
fail($failMessage);
}
else
{
pass($passMessage);
}
}
1;

View File

@@ -0,0 +1,11 @@
use FindBin '$Bin';
require "$Bin/passfail.pl";
require "$Bin/background_process.pl";
sub planetServerRunning
{
my($prefix, $planetName) = @_;
my $passFailMessage = "PlanetServer $planetName reports a true run state";
my $result = runCommandUntil($prefix, "planet $planetName runState", "running", 10);
failOnFalse($result eq "running", $passFailMessage, $passFailMessage);
}

View File

@@ -0,0 +1,69 @@
use FindBin '$Bin';
require "$Bin/passfail.pl";
sub runCommandUntil
{
my($prefix, $command, $expect, $timeout, $evalFunc) = @_;
my $startTime = time();
my $runTime = time() - $startTime;
my $result = "";
if(!defined($timeout))
{
$timeout = 0;
}
do
{
$result = runCommand($prefix, $command);
if($timeout > 0)
{
$runTime = time() - $startTime;
}
} until ($result eq $expect || ($timeout > 0 && $runTime > $timeout) || (defined($evalFunc) && &$evalFunc($result)) );
$returnValue = 0;
if(($result eq $expect || (defined($evalFunc) && &$evalFunc($result))) && ($timeout > 0 && $timeout >= $runTime || $timeout == 0))
{
$returnValue = $result;
}
return $returnValue;
}
sub runCommand
{
my($prefix, $command, $port) = @_;
my $result = "";
$shellCommand = "echo \"$command\" | $prefix/ServerConsole";
if(defined($port))
{
$shellCommand .= " -- -s ServerConsole serverPort=$port";
}
$shellCommand .= " 2>&1|";
open(COMMANDOUTPUT, $shellCommand) or fail("Failed to execute $shellCommand!\n");
while(<COMMANDOUTPUT>)
{
$result .= $_;
}
return $result;
}
sub runTaskCommand
{
my($prefix, $command) = @_;
my $result = "";
$result = runCommand($prefix, $command, 60000);
return $result;
}
1;

View File

@@ -0,0 +1,44 @@
use FindBin '$Bin';
require "$Bin/passfail.pl";
require "$Bin/background_process.pl";
require "$Bin/serverconsole.pl";
$taskManagerPid = 0;
sub taskmanagerStartupShutdown
{
my ($prefix) = @_;
$passFailMessage = "TaskManager startup and shutdown";
failOnFalse(backgroundProcess($prefix, "TaskManager -- -s TaskManager autoStart=false 2>/dev/null", 10, sub {system("echo \"exit\" | debug/ServerConsole -- -s ServerConsole serverPort=60000 > /dev/null");}), $passFailMessage, $passFailMessage);
}
sub clusterStartup
{
my ($prefix) = @_;
$passFailMessage = "TaskManager cluster startup";
$taskManagerPid = startBackgroundProcess($prefix, "TaskManager -- \@taskmanager.cfg 2>/dev/null", 10, sub { return 1; });
$result = "";
do
{
$result = runTaskCommand($prefix, "runState");
} until($result eq "running");
failOnFalse($taskManagerPid > 0, $passFailMessage, $passFailMessage);
do
{
$result = runCommand($prefix, "runState");
} until($result eq "running");
pass("CentralServer cluster startup");
}
sub clusterShutdown
{
my ($prefix) = @_;
do
{
$result = runTaskCommand($prefix, "exit");
} until($result eq "exiting");
}
1;

View File

@@ -0,0 +1,37 @@
my @vcprojs;
print "Getting list\n";
open (FIND, "c:/cygwin/bin/find ../src -name \"settings.rsp\" |");
while (<FIND>)
{
chomp;
s/\/(\w*)\/build\/win32\/settings\.rsp/\/$1\/build\/win32\/$1\.vcproj/g;
push @vcprojs, $_;
}
close (FIND);
print "Editing\n";
open (P4, "| p4 -x - edit");
print P4 join("\n", @vcprojs);
close (P4);
my @errorList;
foreach (@vcprojs)
{
print "Building $_\n";
if (system ("buildVcproj.pl $_"))
{
push @errorList, $_;
}
}
print "Reverting\n";
open (P4, "| p4 -x - revert -a");
print P4 join("\n", @vcprojs);
close (P4);
if (@errorList)
{
die "ERROR!: Failed to build to following projects:\n", (join "\n", @errorList), "\n";
}

View File

@@ -0,0 +1,75 @@
#! /usr/bin/perl
die "usage: perl buildAppearanceTable directory [directory ...]\n" if (@ARGV == 0 || $ARGV[0] eq "-h");
$debug = 0;
# scan the file looking for an appearance or portal layout name
sub do_file
{
local $_;
my $file = $_[0];
print STDERR "scanning $file\n" if ($debug);
open(FILE, $file);
while (<FILE>)
{
chomp;
if (/appearanceFilename/ || /portalLayoutFilename/)
{
s/^[^"]+"//;
s/"[^"]*$//;
tr/A-Z/a-z/;
tr#\\#/#;
$match{$file} = $_ if ($_ ne "");
print STDERR "match $file $_\n" if ($debug);
}
}
close(FILE);
}
# recursively scan a directory
sub do_dir
{
local $_;
my $dir = $_[0];
print STDERR "processing $dir\n" if ($debug);
opendir(DIR, $dir) || return;
my @filenames = readdir(DIR);
closedir(DIR);
for (@filenames)
{
next if $_ eq ".";
next if $_ eq "..";
$pathed = $dir . "/" . $_;
if (-d $pathed)
{
&do_dir($pathed);
}
elsif (/\.tpf$/)
{
&do_file($pathed);
}
}
}
# process all the command line directories
while (@ARGV)
{
&do_dir(shift @ARGV);
}
# spit out tab separated data
foreach (sort keys %match)
{
print $_, "\t", $match{$_}, "\n";
}

View File

@@ -0,0 +1,68 @@
#! /usr/bin/perl
die "usage: perl buildAppearanceUsage buildAppearanceTableOutputFile directory [directory ...]\n" if (@ARGV == 0 || $ARGV[0] eq "-h");
$debug = 0;
# recursively scan a directory
sub do_dir
{
local $_;
my $real = $_[0];
my $display = $_[1];
print STDERR "processing $real\n" if ($debug);
opendir(DIR, $real) || return;
my @filenames = readdir(DIR);
closedir(DIR);
for (@filenames)
{
next if $_ eq ".";
next if $_ eq "..";
if (-d "$real/$_")
{
if ($display ne "")
{
&do_dir("$real/$_", "$display/$_");
}
else
{
&do_dir("$real/$_", "$_");
}
}
elsif (/\.apt$/)
{
$add = "$display/$_";
$add =~ s#^.*/appearance/#appearance/#;
print STDERR "adding file $add\n" if ($debug);
$apt{"$add"} = 0;
}
}
}
$output = shift @ARGV;
# process all the command line directories
while (@ARGV)
{
&do_dir(shift @ARGV, "");
}
open(FILE, $output);
while (<FILE>)
{
chomp;
($object, $appearance) = split(/\t+/);
$apt{$appearance} += 1;
}
close(FILE);
# spit out tab separated data
foreach (sort keys %apt)
{
print $apt{$_}, "\t", $_, "\n";
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,153 @@
#!/bin/sh
# Copyright 2003, Sony Online Entertainment.
# All rights reserved.
#
# Based off a script originally written by Rick Delashmit.
# PURPOSE: Build the infrequently-changing Linux libraries that
# typically live in perforce as binaries. The gcc 2.95.3 C++ libraries are
# incompatible with the gcc 3.x C++ libraries. This script builds
# all the libraries that normally exist in perforce as binaries.
# NOTE: This script will fail if the user has not taken care to remove
# *.a and *.so from their client spec. Those files will be read-only and
# the new compiled versions will fail to replace them. As of this writing,
# the only .a file that should exist in perforce is the one for pcre in
# swg/$BRANCH/src/external/3rd/library/pcre/*.
# USAGE: run this script in the from the base directory of a branch.
#
# Here's some examples of branch directories:
# ~/swg/current
# ~/swg/test
# /swo/swg/current
# BUGS:
#
# * This script does no error checking on the result of the builds. If
# the caller does not watch the output, it is possible this script will fail.
#
# * This script has failed to build in the live branch on Matt Bogue's machine.
# Rick and I could not resolve the apparent bash substitution issue that was
# occurring. Our workaround was to link the live branch's
# external/3rd/library/platform/libs directory to the corresponding directory
# in the current branch.
export BASEDIR=`pwd`
export TEAMBUILDER=0
export PLATFORM=linux
# chatapi
cd $BASEDIR/src/external/3rd/library/soePlatform/ChatAPI2/ChatAPI/projects/Chat/ChatMono
make debug release
mkdir -p ../../../../../libs/Linux-Debug
mkdir -p ../../../../../libs/Linux-Release
cp ../../../lib/debug/libChatAPI.a ../../../../../libs/Linux-Debug/
cp ../../../lib/release/libChatAPI.a ../../../../../libs/Linux-Release/
# stlport
cd $BASEDIR/src/external/3rd/library/stlport453/src
make -f gcc-linux.mak
# zlib
# Note: just link zlib to the zlib already installed under Linux.
mkdir -p $BASEDIR/src/external/3rd/library/zlib/lib/linux
ln -s -f /usr/lib/libz.a $BASEDIR/src/external/3rd/library/zlib/lib/linux/libz.a
# loginapi
cd $BASEDIR/src/external/3rd/library/platform/projects/Session/LoginAPI
make debug release
# commonapi
cd $BASEDIR/src/external/3rd/library/platform/projects/Session/CommonAPI
make debug release
# base
cd $BASEDIR/src/external/3rd/library/platform/utils/Base/linux
make debug_st release_st
# commodityapi
cd $BASEDIR/src/external/3rd/library/soePlatform/CommodityAPI/linux
make debug release
cp $BASEDIR/src/external/3rd/library/soePlatform/libs/Linux-Debug/libcommodityapi.so $BASEDIR/exe/linux/
cp $BASEDIR/src/external/3rd/library/soePlatform/libs/Linux-Debug/libcommodityapi.so $BASEDIR/dev/linux/
# csassistgameapi
cd $BASEDIR/src/external/3rd/library/soePlatform/CSAssist/projects/CSAssist/CSAssistgameapi
make debug release
echo Copying csassistgameapi
mkdir -p ../../../../libs/Linux-Debug
mkdir -p ../../../../libs/Linux-Release
cp debug/libCSAssistgameapi.a ../../../../libs/Linux-Debug/
cp release/libCSAssistgameapi.a ../../../../libs/Linux-Release/
# note: this includes various other libs that CustomerServiceServer expects to link with, so is not compatible
echo Building monapi
# monapi
cd $BASEDIR/src/external/3rd/library/platform/MonAPI2
make clean
make all
# libOracleDB (CommodityServer)
cd $BASEDIR/src/external/3rd/library/soePlatform/CommodityServer/platform/utils/OracleDB
rm -f *.o
ls *.cpp |sed -e '/\.cpp/s///' -e '/^.*$/s//g++ -g -c -I..\/..\/..\/..\/..\/oracle\/include -I.. &.cpp -o &.o/' >comp.sh
source ./comp.sh
rm -f comp.sh
ar rcs libOracleDB.a *.o
mkdir -p ../../../../libs/Linux-Debug
mv -f libOracleDB.a ../../../../libs/Linux-Debug/libOracleDB.a
# libBase (CommodityServer)
cd $BASEDIR/src/external/3rd/library/soePlatform/CommodityServer/platform/utils/Base
rm -f *.o */*.o
ls *.cpp linux/*.cpp |sed -e '/\.cpp/s///' -e '/^.*$/s//g++ -g -c -Dlinux=1 -D_REENTRANT &.cpp -o &.o/' >comp.sh
source ./comp.sh
rm -f comp.sh
ar rcs libBase.a *.o linux/*.o
mkdir -p ../../../../libs/Linux-Debug
mv -f libBase.a ../../../../libs/Linux-Debug/libBase.a
# Create an empty library.a to solve makefile dependencies on libCSAssistBase.a and libCSAssistUnicode.a
echo > /tmp/empty.cpp
g++ -c -o /tmp/empty.o /tmp/empty.cpp
ar crs /tmp/empty.a /tmp/empty.o
mkdir -p $BASEDIR/src/external/3rd/library/soePlatform/libs/Linux-Debug
cp /tmp/empty.a $BASEDIR/src/external/3rd/library/soePlatform/libs/Linux-Debug/libCSAssistBase.a
cp /tmp/empty.a $BASEDIR/src/external/3rd/library/soePlatform/libs/Linux-Debug/libCSAssistUnicode.a
mkdir -p $BASEDIR/src/external/3rd/library/soePlatform/libs/Linux-Release
cp /tmp/empty.a $BASEDIR/src/external/3rd/library/soePlatform/libs/Linux-Release/libCSAssistBase.a
cp /tmp/empty.a $BASEDIR/src/external/3rd/library/soePlatform/libs/Linux-Release/libCSAssistUnicode.a
# Build CommoditiesServer_d and CommoditiesServer_r
# .. start with local OracleDB library
cd $BASEDIR/src/external/3rd/library/soePlatform/CommodityServer/platform/utils/OracleDB
make all
# .. now do the server
cd ../../..
make all
# Copy CommoditiesServer_* to exe/linux. The normal
# make process copies those from exe/linux to dev/linux.
cp commoditysvr $BASEDIR/exe/linux/CommoditiesServer_d
cp commoditysvr $BASEDIR/exe/linux/CommoditiesServer_r
# Remove the debugging symbols from the release version.
# This save 80+ MB.
strip -g $BASEDIR/exe/linux/CommoditiesServer_r
# Copy Commodities server from exe/linux to dev/linux for the first time. Failure to do this
# will cause the build to break.
cp $BASEDIR/exe/linux/CommoditiesServer_* $BASEDIR/dev/linux
# Build the MonAPI2 library.
cd $BASEDIR/src/external/3rd/library/platform/MonAPI2
./bootstrap
./configure --with-udplibrary=../../udplibrary --prefix=`pwd`
make
make install

View File

@@ -0,0 +1,168 @@
#!/usr/bin/perl
use warnings;
use strict;
# =====================================================================
my @crctable =
(
hex("0x00000000"), hex("0x04C11DB7"), hex("0x09823B6E"), hex("0x0D4326D9"), hex("0x130476DC"), hex("0x17C56B6B"), hex("0x1A864DB2"), hex("0x1E475005"),
hex("0x2608EDB8"), hex("0x22C9F00F"), hex("0x2F8AD6D6"), hex("0x2B4BCB61"), hex("0x350C9B64"), hex("0x31CD86D3"), hex("0x3C8EA00A"), hex("0x384FBDBD"),
hex("0x4C11DB70"), hex("0x48D0C6C7"), hex("0x4593E01E"), hex("0x4152FDA9"), hex("0x5F15ADAC"), hex("0x5BD4B01B"), hex("0x569796C2"), hex("0x52568B75"),
hex("0x6A1936C8"), hex("0x6ED82B7F"), hex("0x639B0DA6"), hex("0x675A1011"), hex("0x791D4014"), hex("0x7DDC5DA3"), hex("0x709F7B7A"), hex("0x745E66CD"),
hex("0x9823B6E0"), hex("0x9CE2AB57"), hex("0x91A18D8E"), hex("0x95609039"), hex("0x8B27C03C"), hex("0x8FE6DD8B"), hex("0x82A5FB52"), hex("0x8664E6E5"),
hex("0xBE2B5B58"), hex("0xBAEA46EF"), hex("0xB7A96036"), hex("0xB3687D81"), hex("0xAD2F2D84"), hex("0xA9EE3033"), hex("0xA4AD16EA"), hex("0xA06C0B5D"),
hex("0xD4326D90"), hex("0xD0F37027"), hex("0xDDB056FE"), hex("0xD9714B49"), hex("0xC7361B4C"), hex("0xC3F706FB"), hex("0xCEB42022"), hex("0xCA753D95"),
hex("0xF23A8028"), hex("0xF6FB9D9F"), hex("0xFBB8BB46"), hex("0xFF79A6F1"), hex("0xE13EF6F4"), hex("0xE5FFEB43"), hex("0xE8BCCD9A"), hex("0xEC7DD02D"),
hex("0x34867077"), hex("0x30476DC0"), hex("0x3D044B19"), hex("0x39C556AE"), hex("0x278206AB"), hex("0x23431B1C"), hex("0x2E003DC5"), hex("0x2AC12072"),
hex("0x128E9DCF"), hex("0x164F8078"), hex("0x1B0CA6A1"), hex("0x1FCDBB16"), hex("0x018AEB13"), hex("0x054BF6A4"), hex("0x0808D07D"), hex("0x0CC9CDCA"),
hex("0x7897AB07"), hex("0x7C56B6B0"), hex("0x71159069"), hex("0x75D48DDE"), hex("0x6B93DDDB"), hex("0x6F52C06C"), hex("0x6211E6B5"), hex("0x66D0FB02"),
hex("0x5E9F46BF"), hex("0x5A5E5B08"), hex("0x571D7DD1"), hex("0x53DC6066"), hex("0x4D9B3063"), hex("0x495A2DD4"), hex("0x44190B0D"), hex("0x40D816BA"),
hex("0xACA5C697"), hex("0xA864DB20"), hex("0xA527FDF9"), hex("0xA1E6E04E"), hex("0xBFA1B04B"), hex("0xBB60ADFC"), hex("0xB6238B25"), hex("0xB2E29692"),
hex("0x8AAD2B2F"), hex("0x8E6C3698"), hex("0x832F1041"), hex("0x87EE0DF6"), hex("0x99A95DF3"), hex("0x9D684044"), hex("0x902B669D"), hex("0x94EA7B2A"),
hex("0xE0B41DE7"), hex("0xE4750050"), hex("0xE9362689"), hex("0xEDF73B3E"), hex("0xF3B06B3B"), hex("0xF771768C"), hex("0xFA325055"), hex("0xFEF34DE2"),
hex("0xC6BCF05F"), hex("0xC27DEDE8"), hex("0xCF3ECB31"), hex("0xCBFFD686"), hex("0xD5B88683"), hex("0xD1799B34"), hex("0xDC3ABDED"), hex("0xD8FBA05A"),
hex("0x690CE0EE"), hex("0x6DCDFD59"), hex("0x608EDB80"), hex("0x644FC637"), hex("0x7A089632"), hex("0x7EC98B85"), hex("0x738AAD5C"), hex("0x774BB0EB"),
hex("0x4F040D56"), hex("0x4BC510E1"), hex("0x46863638"), hex("0x42472B8F"), hex("0x5C007B8A"), hex("0x58C1663D"), hex("0x558240E4"), hex("0x51435D53"),
hex("0x251D3B9E"), hex("0x21DC2629"), hex("0x2C9F00F0"), hex("0x285E1D47"), hex("0x36194D42"), hex("0x32D850F5"), hex("0x3F9B762C"), hex("0x3B5A6B9B"),
hex("0x0315D626"), hex("0x07D4CB91"), hex("0x0A97ED48"), hex("0x0E56F0FF"), hex("0x1011A0FA"), hex("0x14D0BD4D"), hex("0x19939B94"), hex("0x1D528623"),
hex("0xF12F560E"), hex("0xF5EE4BB9"), hex("0xF8AD6D60"), hex("0xFC6C70D7"), hex("0xE22B20D2"), hex("0xE6EA3D65"), hex("0xEBA91BBC"), hex("0xEF68060B"),
hex("0xD727BBB6"), hex("0xD3E6A601"), hex("0xDEA580D8"), hex("0xDA649D6F"), hex("0xC423CD6A"), hex("0xC0E2D0DD"), hex("0xCDA1F604"), hex("0xC960EBB3"),
hex("0xBD3E8D7E"), hex("0xB9FF90C9"), hex("0xB4BCB610"), hex("0xB07DABA7"), hex("0xAE3AFBA2"), hex("0xAAFBE615"), hex("0xA7B8C0CC"), hex("0xA379DD7B"),
hex("0x9B3660C6"), hex("0x9FF77D71"), hex("0x92B45BA8"), hex("0x9675461F"), hex("0x8832161A"), hex("0x8CF30BAD"), hex("0x81B02D74"), hex("0x857130C3"),
hex("0x5D8A9099"), hex("0x594B8D2E"), hex("0x5408ABF7"), hex("0x50C9B640"), hex("0x4E8EE645"), hex("0x4A4FFBF2"), hex("0x470CDD2B"), hex("0x43CDC09C"),
hex("0x7B827D21"), hex("0x7F436096"), hex("0x7200464F"), hex("0x76C15BF8"), hex("0x68860BFD"), hex("0x6C47164A"), hex("0x61043093"), hex("0x65C52D24"),
hex("0x119B4BE9"), hex("0x155A565E"), hex("0x18197087"), hex("0x1CD86D30"), hex("0x029F3D35"), hex("0x065E2082"), hex("0x0B1D065B"), hex("0x0FDC1BEC"),
hex("0x3793A651"), hex("0x3352BBE6"), hex("0x3E119D3F"), hex("0x3AD08088"), hex("0x2497D08D"), hex("0x2056CD3A"), hex("0x2D15EBE3"), hex("0x29D4F654"),
hex("0xC5A92679"), hex("0xC1683BCE"), hex("0xCC2B1D17"), hex("0xC8EA00A0"), hex("0xD6AD50A5"), hex("0xD26C4D12"), hex("0xDF2F6BCB"), hex("0xDBEE767C"),
hex("0xE3A1CBC1"), hex("0xE760D676"), hex("0xEA23F0AF"), hex("0xEEE2ED18"), hex("0xF0A5BD1D"), hex("0xF464A0AA"), hex("0xF9278673"), hex("0xFDE69BC4"),
hex("0x89B8FD09"), hex("0x8D79E0BE"), hex("0x803AC667"), hex("0x84FBDBD0"), hex("0x9ABC8BD5"), hex("0x9E7D9662"), hex("0x933EB0BB"), hex("0x97FFAD0C"),
hex("0xAFB010B1"), hex("0xAB710D06"), hex("0xA6322BDF"), hex("0xA2F33668"), hex("0xBCB4666D"), hex("0xB8757BDA"), hex("0xB5365D03"), hex("0xB1F740B4")
);
my %crc;
my %offset;
my $offset = 0;
# =====================================================================
sub crc
{
use integer;
my $string = $_[0];
return 0 if ($string eq "");
my $crc_init = hex("0xffffffff") & 0xffffffff;
my $crc = $crc_init;
foreach (split(//, $string))
{
$crc = ($crctable[(($crc>>24) ^ ord($_)) & 255] ^ ($crc << 8) & 0xffffffff);
}
return $crc ^ $crc_init & 0xffffffff;
}
# =====================================================================
die "usage: buildCrcStringTable.pl [-t tabFileName.ext] outputFileName.ext [stringFile...]\n" .
"-t : generate tab delimited output file as well\n" .
"If the output file name extension is .mif, then the text mif file will be generated.\n" .
"Otherwise, the binary IFF data will be written.\n" if (@ARGV < 1 || $ARGV[0] =~ /^[\/-][h\?]$/);
my $outputFileName = shift;
my $tab = 0;
my $tabFileName = "";
if ($outputFileName eq "-t")
{
$tab = 1;
$tabFileName = shift;
$outputFileName = shift;
}
while (<>)
{
chomp();
if ($_ ne "")
{
my $crc = sprintf("0x%08x", crc($_));
die "crc string clash for $crc:\n\t$crc{$crc}\n\t$_\n" if (defined($crc{$crc}) && $_ ne $crc{$crc});
$crc{$crc} = $_;
}
}
open(OUTPUT, "> tempfile") || die "could not open tempfile\n";
my $old = select(OUTPUT);
print "form \"CSTB\"\n";
print "{\n";
print "\tform \"0000\"\n";
print "\t{\n";
print "\t\tchunk \"DATA\"\n";
print "\t\t{\n";
print "\t\t\tint32 ", scalar(keys(%crc)), "\n";
print "\t\t}\n";
print "\n";
print "\t\tchunk \"CRCT\"\n";
print "\t\t{\n";
foreach (sort keys %crc)
{
print "\t\t\tuint32 ", $_, "\n";
$offset{$_} = $offset;
$offset += length($crc{$_}) + 1;
}
print "\t\t}\n";
print "\n";
print "\t\tchunk \"STRT\"\n";
print "\t\t{\n";
foreach (sort keys %crc)
{
print "\t\t\tint32 ", $offset{$_}, "\n";
}
print "\t\t}\n";
print "\n";
print "\t\tchunk \"STNG\"\n";
print "\t\t{\n";
foreach (sort keys %crc)
{
print "\t\t\tcstring \"", $crc{$_}, "\" /* ", $_, " */\n";
}
print "\t\t}\n";
print "\t}\n";
print "}\n";
select $old;
close(OUTPUT);
if ($outputFileName =~ /\.mif/)
{
rename("tempfile", $outputFileName);
}
else
{
print $outputFileName, "\n";
system("bin/Miff -i tempfile -o $outputFileName");
unlink("tempfile");
}
if ($tab)
{
open(OUTPUT, ">" . $tabFileName) || die "could not open $tabFileName\n";
foreach (sort keys %crc)
{
print OUTPUT $_, "\t", $crc{$_}, "\n";
}
close(OUTPUT);
}

View File

@@ -0,0 +1,138 @@
use strict;
use warnings;
my $branch;
my $all = "";
my $only = "";
# =====================================================================
sub perforceWhere
{
# find out where a perforce file resides on the local machine
my $result;
{
open(P4, "p4 where $_[0] |");
while ( <P4> )
{
next if ( /^-/ );
chomp;
my @where = split;
$result = $where[2];
}
close(P4);
}
return $result;
}
sub usage
{
die "usage: buildObjectTemplateCrcStringTables [--local|--all|--only <changelist#>] <current|test|live|x1|x2|ep3|demo|s#>\n" .
"\t--local : include pending files only from the local client\n" .
"\t--all : include pending files from all clients\n" .
"\t--only <changelist#> : include pending files only from <changelist#>\n" .
"\tif no option is provided, --local is assumed.\n";
}
# =====================================================================
sub perforceGatherAndPrune
{
local $_;
my %files;
foreach my $spec (@_)
{
open(P4, "p4 files $spec/... |");
while (<P4>)
{
chomp;
next if (/ delete /)/
s%//depot/swg/$branch/data/sku\.0/sys\.(shared|server)/compiled/game/%%;
s/#.*//;
$files{$_} = 1;
}
close(P4);
open(P4, "p4 opened " . $all . " " . $only . " $spec/... |");
while (<P4>)
{
chomp;
s%//depot/swg/$branch/data/sku\.0/sys\.(shared|server)/compiled/game/%%;
s/#.*//;
$files{$_} = 1;
}
close(P4);
}
return sort keys %files;
}
# =====================================================================
if ($#ARGV == 1 || $#ARGV == 2)
{
if ($ARGV[0] eq "--local")
{
$all = "";
}
elsif ($ARGV[0] eq "--all")
{
$all = "-a";
}
elsif ($ARGV[0] eq "--only" && $#ARGV == 2)
{
$all = "";
$only = "-c " . $ARGV[1];
shift;
}
else
{
usage();
}
shift;
}
usage() unless (defined($ARGV[0]) && $ARGV[0] =~ m%^(current|test|stage|live|x1|x2|ep3|demo|s\d+)$%);
$branch = $ARGV[0];
my $buildCrcStringTable = perforceWhere("//depot/swg/$branch/tools/buildCrcStringTable.pl");
{
my $tab = perforceWhere("//depot/swg/$branch/dsrc/sku.0/sys.client/built/game/misc/object_template_crc_string_table.tab");
my $output = perforceWhere("//depot/swg/$branch/data/sku.0/sys.client/built/game/misc/object_template_crc_string_table.iff");
print "building client object template strings:\n\t$tab\n\t$output\n";
system("p4 edit $tab $output");
my @files = perforceGatherAndPrune(
"//depot/swg/$branch/data/sku.0/sys.shared/compiled/game/object",
"//depot/swg/$branch/data/sku.0/sys.server/compiled/game/object/creature/player");
open(B, "| perl $buildCrcStringTable -t $tab $output");
foreach (@files)
{
print B $_, "\n";
}
close(B);
}
{
my $tab = perforceWhere("//depot/swg/$branch/dsrc/sku.0/sys.server/built/game/misc/object_template_crc_string_table.tab");
my $output = perforceWhere("//depot/swg/$branch/data/sku.0/sys.server/built/game/misc/object_template_crc_string_table.iff");
print "building server object template strings:\n\t$tab\n\t$output\n";
system("p4 edit $tab $output");
my @files = perforceGatherAndPrune(
"//depot/swg/$branch/data/sku.0/sys.shared/compiled/game/object",
"//depot/swg/$branch/data/sku.0/sys.server/compiled/game/object");
open(B, "| perl $buildCrcStringTable -t $tab $output");
foreach (@files)
{
print B $_, "\n";
}
close(B);
}

View File

@@ -0,0 +1,120 @@
#!/usr/bin/perl
use strict;
use warnings;
my $branch;
my $all = "";
my $only = "";
# =====================================================================
sub perforceWhere
{
# find out where a perforce file resides on the local machine
my $result;
{
open(P4, "p4 where $_[0] |");
while ( <P4> )
{
next if ( /^-/ );
chomp;
my @where = split;
$result = $where[2];
}
close(P4);
}
return $result;
}
sub usage
{
die "usage: buildQuestCrcStringTables [--local|--all|--only <changelist#>] <current|stage|test|live|x1|x2|ep3|demo|s#>\n" .
"\t--local : include pending files only from the local client\n" .
"\t--all : include pending files from all clients\n" .
"\t--only <changelist#> : include pending files only from <changelist#>\n" .
"\tif no option is provided, --local is assumed.\n";
}
# =====================================================================
sub perforceGatherAndPrune
{
local $_;
my %files;
foreach my $spec (@_)
{
open(P4, "p4 files $spec/... |");
while (<P4>)
{
chomp;
next if (/ delete /)/
s%//depot/swg/$branch/data/sku\.0/sys\.(shared|server)/compiled/game/datatables/questlist/%%;
s/\.iff//;
s/#.*//;
$files{$_} = 1;
}
close(P4);
open(P4, "p4 opened " . $all . " " . $only . " $spec/... |");
while (<P4>)
{
chomp;
s%//depot/swg/$branch/data/sku\.0/sys\.(shared|server)/compiled/game/datatables/questlist/%%;
s/\.iff//;
s/#.*//;
$files{$_} = 1;
}
close(P4);
}
return sort keys %files;
}
# =====================================================================
if ($#ARGV == 1 || $#ARGV == 2)
{
if ($ARGV[0] eq "--local")
{
$all = "";
}
elsif ($ARGV[0] eq "--all")
{
$all = "-a";
}
elsif ($ARGV[0] eq "--only" && $#ARGV == 2)
{
$all = "";
$only = "-c " . $ARGV[1];
shift;
}
else
{
usage();
}
shift;
}
usage() unless (defined($ARGV[0]) && $ARGV[0] =~ m%^(current|stage|test|live|x1|x2|ep3|demo|s\d+)$%);
$branch = $ARGV[0];
{
my $tab = perforceWhere("//depot/swg/$branch/dsrc/sku.0/sys.shared/built/game/misc/quest_crc_string_table.tab");
my $output = perforceWhere("//depot/swg/$branch/data/sku.0/sys.shared/built/game/misc/quest_crc_string_table.iff");
print "building quest template strings:\n\t$tab\n\t$output\n";
system("p4 edit $tab $output");
my @files = perforceGatherAndPrune("//depot/swg/$branch/data/sku.0/sys.shared/compiled/game/datatables/questlist");
open(B, "| perl buildCrcStringTable.pl -t $tab $output");
foreach (@files)
{
print B $_, "\n";
}
close(B);
}

View File

@@ -0,0 +1,53 @@
use Cwd;
use strict;
use ConfigFile;
use Perforce;
use TreeFile;
my $debug = 1;
my $justPrint = 0;
# Grab branch from commandline, default to current.
my $branch = shift;
$branch = 'current' if !defined($branch);
print "branch: $branch\n" if $debug;
# Grab p4 changelist number for treefile.
my $p4ChangelistOutput = `p4 changes -m1 //depot/swg/$branch/data/...#have`;
my $p4ChangelistNumber = $1 if ($p4ChangelistOutput =~ m/\s*Change\s*(\d+)/) || die "Failed to find changelist number";
print "changelist number: $p4ChangelistNumber\n" if $debug;
# Construct config file common.cfg file location. We just need the loose-file treefile paths.
my $configPathName = Perforce::findOnDiskFileName("//depot/swg/$branch/exe/win32/client.cfg");
$configPathName =~ s!\\!/!g;
print "config file pathname: [$configPathName]\n" if $debug;
# Setup ConfigFile.
ConfigFile::processConfigFile($configPathName) if !$justPrint;
# Build treefile map pathname, places it in current directory.
my $treefileLookupPathName = getcwd();
$treefileLookupPathName .= '/' if !($treefileLookupPathName =~ m!/$!);
$treefileLookupPathName .= "treefile-xlat-$branch-$p4ChangelistNumber.dat";
print "treefile lookup pathname: [$treefileLookupPathName]\n" if $debug;
# Open treefile map filehandle.
my $fileHandle;
die "could not open treefile handle: $!" if !($justPrint || open($fileHandle, "> " . $treefileLookupPathName));
# Construct rooted directory path for relative treefile searchpath locations.
# Just chop off everything after and including the last slash in the config pathname.
my $rootedBaseSearchPath = $configPathName;
$rootedBaseSearchPath =~ s!/[^/]+$!!;
print "treefile rooted base searchpath: [$rootedBaseSearchPath]\n" if $debug;
# Build the TreeFile map file.
TreeFile::buildFileLookupTable(1, $rootedBaseSearchPath) if !$justPrint;
# Save the TreeFile map file.
TreeFile::saveFileLookupTable($fileHandle) if !$justPrint;
# Close the map file.
die "could not close treefile handle: $!" if !($justPrint || close($fileHandle));
print "Done.\n" if $debug;

View File

@@ -0,0 +1,691 @@
#! /usr/bin/perl
# ======================================================================
# ======================================================================
use warnings;
use strict;
use Socket;
use Getopt::Long;
use File::Copy;
# ======================================================================
# Constants
# ======================================================================
use constant START_BOOTLEG_TEST => "A";
use constant END_COMMUNICATION => "B";
use constant SUCCESSFUL_TEST => "C";
use constant UNSUCCESSFUL_TEST => "D";
use constant SERVER_READY => "E";
use constant BOOTLEG_MISMATCH => "F";
use constant CLIENT_KILL => "G";
use constant CLIENT_OK => "H";
use constant GOT_BUILD_CLUSTER_VERSION => "I";
use constant FAILED_GETTING_BUILD_CLUSTER_VERSION => "J";
use constant START_UPKEEP => "K";
use constant START_BOOTLEG_SEND => "L";
use constant BOOTLEG_SEND_DIRECTORY => "M";
use constant BOOTLEG_SEND_FILE => "N";
use constant END_BOOTLEG_SEND => "O";
use constant START_EMAIL => "P";
# ======================================================================
# Globals
# ======================================================================
my $name = $0;
$name =~ s/^(.*)\\//;
my $depotdir = "/swg";
my $bootlegdir = "/swg/bootlegs";
my $logfile = "build_bootleg.log";
my $win32machine = "64.37.133.173";
my $port = "21498";
my $emailRecipients = "vthakkar\@soe.sony.com";
my $waittime = "180";
my $branch = "";
my $oldbootleg = "";
my $newbootleg = "";
my $loginpid;
my $taskpid;
my @steps = (0, 0, 0, 0, 0, 0, 0, 0);
# ======================================================================
# Subroutines
# ======================================================================
sub usage
{
print "\n\t$name <optional parameters> <branch>\n\n".
"\tOptional parameters:\n\n".
"\t\t--no_script\t: Don't do a script recompile\n".
"\t\t--no_build\t: Don't build a new bootleg\n".
"\t\t--no_patch\t: Don't create a patchtree file\n".
"\t\t--no_send\t: Don't send build / patch results to win32 machine\n".
"\t\t--no_install\t: Don't install newest bootleg\n".
"\t\t--no_test\t: Don't perform test on bootleg\n".
"\t\t--no_email\t: Don't send email about results\n".
"\t\t--no_upkeep\t: Don't perform upkeep on bootleg directories\n".
"\n\tWarning: Some options depend on others, some combinations may not work.\n";
die "\n";
}
sub writelog
{
my $message = shift @_;
chomp $message;
my ($sec, $min, $hr, $day, $mon, $yr) = localtime time;
my $timestamp = sprintf "%4s-%02s-%02s\t%02s:%02s:%02s", ($yr + 1900), ($mon + 1), $day, $hr, $min, $sec;
print LOG join("\t", $timestamp, $message), "\n";
}
sub fatal
{
my $message = shift @_;
print "Fatal error running: $message\n";
writelog("Fatal error running: $message");
close(LOG);
die;
}
sub unbuffer
{
my $oldSelect = select($_[0]);
$| = 1;
select($oldSelect);
}
sub unbufferReadline
{
my ($fh) = @_;
my $buffer;
my $return = "";
while(sysread($fh, $buffer, 1))
{
$return .= $buffer;
last if($buffer eq "\n");
}
return $return;
}
sub perforceWhere
{
local $_;
# find out where a perforce file resides on the local machine
my $result;
{
open(P4, "p4 where $_[0] |");
$_ = <P4>;
chomp;
my @where = split;
$result = $where[2];
close(P4);
}
return $result;
}
sub openClientSocket
{
socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || closeServer("socket failed\n");
{
my $destination = inet_aton($win32machine) || closeServer("inet_aton failed\n");
my $paddr = sockaddr_in($port, $destination);
connect(SOCKET, $paddr) || closeServer("connect failed\n");
# unbuffer the socket
my $oldSelect = select(SOCKET);
$| = 1;
select($oldSelect);
# put the socket into binary mode
binmode SOCKET;
}
}
sub buildBootleg
{
my $win32complete = 0;
my $linuxcomplete = 0;
print "Building bootleg...\n";
writelog("Building bootleg");
open(LINUXBUILD, "perl ${depotdir}/swg/current/tools/build_script_linux_new.pl $branch -bootleg -incrediBuild 2>&1 |") or fatal "Error running build_script_linux.pl\n";
while(<LINUXBUILD>)
{
print;
writelog($_);
$newbootleg = $1 if(/^Syncing to $branch\@(\d+)/);
$win32complete = 1 if(/^Windows build returned 0/);
$linuxcomplete = 1 if(/^Linux build returned 0/);
}
close(LINUXBUILD);
print "linux build incomplete\n" if(!$linuxcomplete);
print "windows build incomplete\n" if(!$win32complete);
print "Completed building bootleg $newbootleg.\n\n" if($win32complete && $linuxcomplete);
writelog("Bootleg: $newbootleg, Linux complete: $linuxcomplete, Windows complete: $win32complete");
($win32complete && $linuxcomplete) ? return 1 : return 0;
}
sub buildPatchTree
{
my $patch_tree_complete = 0;
my $patch_changelist = 0;
print "Building patch tree...\n";
writelog("Building patch tree");
mkdir "$bootlegdir/$branch/$newbootleg/patch" || fatal "mkdir for patchtree failed";
open(PATCHTREE, "perl ${depotdir}/swg/current/tools/CheckPatchTreeSize.pl --sync --changelist=$newbootleg --save_treefile=$bootlegdir/$branch/$newbootleg/patch/bootlegpatch.tre |") or fatal "Error running CheckPatchTreeSize.pl\n";
while(<PATCHTREE>)
{
print;
writelog($_);
$patch_changelist = $1 if(/^Most recent final manifest at revision \d+, patch \d+, changelist (\d+)/);
$patch_tree_complete = 1 if(/^Size of \.tre is: \d+$/);
}
close(PATCHTREE);
move "$bootlegdir/$branch/$newbootleg/patch/bootlegpatch.tre", "$bootlegdir/$branch/$newbootleg/patch/bootleg_${patch_changelist}_${newbootleg}.tre";
print "Patch tree build incomplete.\n\n" if(!$patch_tree_complete);
print "Patch tree build complete.\n\n" if($patch_tree_complete);
writelog("Patch Tree complete: $patch_tree_complete");
return $patch_tree_complete;
}
sub sendBootleg
{
print "Sending bootleg / patch to win32 machine...\n";
writelog("Sending bootleg / patch to win32 machine...");
openClientSocket();
print SOCKET START_BOOTLEG_SEND;
print SOCKET pack("N", length $branch);
print SOCKET $branch;
print SOCKET pack("N", $newbootleg);
# Build an array of what directories to send over
my @directories;
push @directories, "patch" if(-d "$bootlegdir/$branch/$newbootleg/patch");
push @directories, "servers" if(-d "$bootlegdir/$branch/$newbootleg/servers");
while(@directories = sort @directories)
{
my $dir = shift @directories;
# Tell the windows machine to get a new directory
print SOCKET BOOTLEG_SEND_DIRECTORY;
print SOCKET pack("N", length $dir);
print SOCKET $dir;
opendir DH, "$bootlegdir/$branch/$newbootleg/$dir" || die "could not open directory\n";
foreach my $fileName (sort readdir DH)
{
next if($fileName eq "." || $fileName eq "..");
push @directories, "$dir/$fileName" if(-d "$bootlegdir/$branch/$newbootleg/$dir/$fileName");
next if(!-f "$bootlegdir/$branch/$newbootleg/$dir/$fileName");
my $fileSize = -s "$bootlegdir/$branch/$newbootleg/$dir/$fileName";
print "Sending file $fileName ($fileSize bytes)\n";
writelog("Sending file $fileName ($fileSize bytes)");
print SOCKET BOOTLEG_SEND_FILE;
print SOCKET pack("NN", length $fileName, $fileSize);
print SOCKET $fileName;
open(F, "<$bootlegdir/$branch/$newbootleg/$dir/$fileName");
binmode(F);
while ($fileSize)
{
my $buffer;
my $readSize = 16 * 1024;
$readSize = $fileSize if ($fileSize < $readSize);
my $readResult = read(F, $buffer, $readSize);
die "unexpected end of file" if (!defined($readResult));
die "did not read what we expected to" if ($readResult != $readSize);
print SOCKET $buffer;
$fileSize -= $readResult;
}
die "copied all the bytes but not at EOF" if (!eof(F));
close(F);
}
closedir DH;
}
print SOCKET END_BOOTLEG_SEND;
print "Finished sending to win32 machine.\n";
writelog("Finished sending to win32 machine.");
close(SOCKET);
return 1;
}
sub installBootleg
{
print "Installing bootleg...\n";
writelog("Installing bootleg");
open(INSTALL, "perl " . perforceWhere("//depot/swg/current/tools/InstallBootleg.pl") . " --list --force_newest --server_only --install_as_build_cluster $branch |") or fatal "Error running InstallBootleg.pl\n";
my $complete = 0;
while(<INSTALL>)
{
print;
writelog($_);
$complete = 1 if(/^Update complete\./);
$oldbootleg = $1 if($oldbootleg eq "" && /^\d+\s+(\d+)\s+blessed/);
$newbootleg = $1 if(/^Updating to build: (\d+)/);
}
close(INSTALL);
print "Bootleg installation incomplete\n" if(!$complete);
print "Completed installing bootleg.\n\n" if($complete);
writelog("OldBootleg: $oldbootleg, InstallBootleg complete: $complete");
return $complete;
}
sub closeServer
{
print "Fatal Error: Killing forked processes\n";
endServer();
fatal $_[0];
}
sub startServer
{
my $loginServer = "debug/LoginServer";
my $taskManager = "debug/TaskManager";
writelog("Starting Server");
my $serverdir = perforceWhere("//depot/swg/$branch/bootleg/linux/fakefile");
$serverdir =~ s/fakefile$//;
chdir($serverdir) || fatal "Cannot change directory to $serverdir\n";
print "Starting up server...\n";
$loginpid = open(LOGINSERVER, "$loginServer -- \@loginServer.cfg 2>&1 |") or closeServer("Can't open LoginServer\n");
binmode LOGINSERVER;
while(<LOGINSERVER>)
{
writelog("LoginServer: $_") if(/\S+/);
last if(/^Log observer setup/);
}
$taskpid = open(TASKMANAGER, "$taskManager -- \@taskmanager.cfg 2>&1 |") or closeServer("Can't open TaskManager\n");
binmode TASKMANAGER;
while(<TASKMANAGER>)
{
writelog("TaskManager: $_") if(/\S+/);
last if(/^Preload finished on all planets/);
}
}
sub endServer
{
writelog("Ending Server");
print "Shutting down server.\n";
kill 1, $taskpid if(defined $taskpid);
kill 1, $loginpid if(defined $loginpid);
system("killall CommoditiesServer");
system("killall ChatServer");
close(TASKMANAGER);
close(LOGINSERVER);
}
sub startClient
{
writelog("Starting Client");
print "Starting up client...\n";
openClientSocket();
print SOCKET START_BOOTLEG_TEST;
print SOCKET pack("N", length $branch);
print SOCKET $branch;
}
sub endClient
{
writelog("Ending Client");
print SOCKET CLIENT_KILL;
print "Shutting down client.\n";
close(SOCKET);
}
sub checkResponses
{
writelog("Verifying server and client responses");
my $loginsuccess = 0;
my $tasksuccess = 0;
my $buffer;
print "Verifying client and server have same bootleg installation.\n";
read(SOCKET, $buffer, 4) == 4 or fatal "Error reading from win32 machine\n";
my $clientbootleg = unpack("N", $buffer);
if($clientbootleg ne $newbootleg)
{
writelog("Mismatch in client / server bootlegs - client: $clientbootleg, server: $newbootleg");
print "Mismatch in client / server bootlegs - client: $clientbootleg, server: $newbootleg\n";
print SOCKET BOOTLEG_MISMATCH;
return 0;
}
print "Both client and server have bootleg $newbootleg installed\n";
writelog("Both client and server have bootleg $newbootleg installed");
print SOCKET SERVER_READY;
my $starttime = time;
writelog("Beginning test with client - timeout of $waittime seconds");
# used to create non-blocking reading of both filehandles
while(1)
{
my $rin = '';
my $rout;
my $line;
vec($rin, fileno(LOGINSERVER), 1) = 1;
vec($rin, fileno(TASKMANAGER), 1) = 1;
if(select($rout=$rin, undef, undef, 0))
{
if (vec($rout, fileno(LOGINSERVER), 1))
{
$line = unbufferReadline(\*LOGINSERVER);
if(defined $line)
{
writelog("LoginServer: $line") if($line =~ /\S+/);
++$loginsuccess if($loginsuccess == 0 && $line =~ /^connection opened for service on port \d+/);
++$loginsuccess if($loginsuccess == 1 && $line =~ /^Encrypting with key:/);
++$loginsuccess if($loginsuccess == 2 && $line =~ /^Client connected\. Station Id: \d+, Username: bootleg/);
++$loginsuccess if($loginsuccess == 3 && $line =~ /^Client \d+ disconnected/);
last if ($line =~ /ERROR/ or $line =~ /FATAL/);
}
}
if (vec($rout, fileno(TASKMANAGER), 1))
{
$line = unbufferReadline(\*TASKMANAGER);
if(defined $line)
{
writelog("TaskManager: $line") if($line =~ /\S+/);
++$tasksuccess if($tasksuccess == 0 && $line =~ /^connection opened for service on port \d+/);
++$tasksuccess if($tasksuccess == 1 && $line =~ /^Opened connection with client/);
++$tasksuccess if($tasksuccess == 2 && $line =~ /^Recieved ClientIdMsg/);
++$tasksuccess if($tasksuccess == 3 && $line =~ /^Decrypting with key: /);
++$tasksuccess if($tasksuccess == 4 && $line =~ /^succeeded/);
++$tasksuccess if($tasksuccess == 5 && $line =~ /^ValidateAccountMessage/);
++$tasksuccess if($tasksuccess == 6 && $line =~ /^ValidateAccountReplyMessage/);
++$tasksuccess if($tasksuccess == 7 && $line =~ /^Permissions for \d+:/);
++$tasksuccess if($tasksuccess == 8 && $line =~ /canLogin/);
++$tasksuccess if($tasksuccess == 9 && $line =~ /canCreateRegularCharacter/);
++$tasksuccess if($tasksuccess == 10 && $line =~ /^Recvd SelectCharacter message for \d+/);
++$tasksuccess if($tasksuccess == 11 && $line =~ /^Got ValidateCharacterForLoginMessage acct \d+, character \d+/);
++$tasksuccess if($tasksuccess == 12 && $line =~ /^Pending character \d+ is logging in or dropping/);
last if ($line =~ /ERROR/ or $line =~ /FATAL/);
}
}
}
return 0 if((time - $starttime) > $waittime);
last if($loginsuccess == 4 && $tasksuccess == 13);
}
writelog("LoginServer success: $loginsuccess/4, Taskmanager success: $tasksuccess/13");
return 0 if($loginsuccess != 4 || $tasksuccess != 13);
# Tell win32 machine that the client is ok (don't need to kill it)
print SOCKET CLIENT_OK;
read(SOCKET, $buffer, 1) == 1 or fatal "Error reading from win32 machine\n";
my $clientsuccess = 0;
$clientsuccess = 1 if($buffer eq SUCCESSFUL_TEST);
writelog("Client success: $clientsuccess/1");
return 0 if($clientsuccess != 1);
return 1;
}
sub testBootleg
{
print "Testing bootleg...\n";
writelog("Testing bootleg");
my $test = 0;
startServer();
startClient();
$test = checkResponses();
endServer();
endClient();
fatal "Test for bootleg $newbootleg unsuccessful\n" if(!$test);
print "Testing successful.\n\n";
writelog("Test for bootleg successful: $test");
open(BLESS, ">$bootlegdir/$branch/$newbootleg/blessed.txt");
close(BLESS);
return 1;
}
sub email
{
return 0 if($newbootleg eq "");
# Get old bootleg if we don't know it
if($oldbootleg eq "")
{
openClientSocket();
print SOCKET START_EMAIL;
# Tell the client which bootleg to ignore
print SOCKET pack("N", length $newbootleg);
print SOCKET $newbootleg;
my $buffer;
return 0 if(read(SOCKET, $buffer, 4) != 4);
my $oldBootlegLength = unpack("N", $buffer);
return 0 if($oldBootlegLength == 0);
return 0 if(read(SOCKET, $oldbootleg, $oldBootlegLength) != $oldBootlegLength);
close(SOCKET);
}
print "Emailing about changes from bootleg $oldbootleg to $newbootleg...\n";
writelog("Emailing changes from $oldbootleg to $newbootleg");
return 0 if($oldbootleg eq "");
open(EMAIL, "| mail -s \"[bootleg] $branch.$newbootleg.0 is up\" $emailRecipients");
print EMAIL "${bootlegdir}/\n".
"\n-Vijay\n\n";
print EMAIL "Changes between $oldbootleg and $newbootleg\n";
open(CHANGES, "perl ${depotdir}/swg/current/tools/BuildChanges.pl -i //depot/swg/$branch/... $oldbootleg $newbootleg |");
while(<CHANGES>)
{
next if(/^Change (\d+) on/ || /^\[(public|internal)\]/ || /^\n/ || /.?none.?/i || /n(\/|\.)a/i || /^---/ || /ignoring script recompile/i);
s/^\s*-?\s*//;
print EMAIL "\t- $_";
}
close(CHANGES);
print "Completed emailing.\n\n";
writelog("Completed emailing.");
return 1;
}
sub upkeep
{
my $buffer;
print "Performing upkeep on bootleg directory for $branch...\n";
writelog("Performing upkeep on bootleg directory for $branch...");
openClientSocket();
print SOCKET START_UPKEEP;
print SOCKET pack("N", length $branch);
print SOCKET $branch;
return 0 if(read(SOCKET, $buffer, 1) != 1);
if($buffer eq FAILED_GETTING_BUILD_CLUSTER_VERSION)
{
print "Failed getting build cluster version\n";
writelog("Failed getting build cluster version");
return 0;
}
elsif($buffer eq GOT_BUILD_CLUSTER_VERSION)
{
return 0 if(read(SOCKET, $buffer, 4) != 4);
my $buildClusterBootleg = unpack("N", $buffer);
print "Build cluster bootleg version is $buildClusterBootleg\n";
writelog("Build cluster bootleg version is $buildClusterBootleg");
}
else
{
print "Got incorrect return from win32 machine\n";
writelog("Got incorrect return from win32 machine.");
return 0;
}
while(1)
{
return 0 if(read(SOCKET, $buffer, 4) != 4);
my $bootlegVer = unpack("N", $buffer);
last if($bootlegVer == 0);
print "Removed bootleg $branch/$bootlegVer.\n";
writelog("Removed bootleg $branch/$bootlegVer.");
}
while(1)
{
return 0 if(read(SOCKET, $buffer, 4) != 4);
my $pdbFileLength = unpack("N", $buffer);
last if($pdbFileLength == 0);
return 0 if(read(SOCKET, $buffer, $pdbFileLength) != $pdbFileLength);
print "Removed pdb file $buffer.\n";
writelog("Removed pdb file $buffer.");
}
close(SOCKET);
}
sub submitOpenFiles
{
local $_;
my @files;
open(P4, "p4 -ztag opened -c default |");
while (<P4>)
{
chomp;
push (@files, $_) if (s/^\.\.\. depotFile //);
}
close(P4);
my $tmpfile = "submit.tmp";
# submit all the open files
open(TMP, ">" . $tmpfile);
print TMP "Change:\tnew\n";
print TMP "\nDescription:\n";
foreach (@_)
{
print TMP "\t", $_, "\n";
}
print TMP "\nFiles:\n";
foreach (@files)
{
print TMP "\t", $_, "\n";
}
close(TMP);
my $result = system("p4 submit -i < $tmpfile");
fatal "p4 submit failed" if ($result != 0);
unlink($tmpfile);
}
sub scriptRecompile
{
print "Recompiling scripts...\n";
writelog("Syncing perforce for script recompile...");
system("p4 sync //depot/swg/$branch/...") == 0 || return 0;
writelog("Sync perforce complete.");
writelog("Recompiling scripts...");
my $result = system("perl ${depotdir}/swg/current/tools/recompileAllScripts.pl $branch");
writelog("Recompile scripts returned $result (success = 0)");
if ($result != 0)
{
my $attach = "";
$attach .= " -a pythonPreprocessorStderr.log" if (-s "pythonPreprocessorStderr.log");
$attach .= " -a javac.log" if (-s "javac.log");
system("mutt -s \"[BUILDLOG $branch] script recompile failed, errors attached\" $attach $emailRecipients < /dev/null");
system("p4 revert -c default //depot/... > /dev/null");
return 0;
}
system("p4 revert -a > /dev/null");
submitOpenFiles("[automated]", "Script recompile for bootleg build");
print "Recompile scripts successful.\n";
return 1;
}
# ======================================================================
# Main
# ======================================================================
usage() if(!GetOptions('no_script' => \$steps[0], 'no_build' => \$steps[1], 'no_patch' => \$steps[2], 'no_send' => \$steps[3], 'no_install' => \$steps[4], 'no_test' => \$steps[5], 'no_email' => \$steps[6], 'no_upkeep' => \$steps[7]));
usage() if(@ARGV != 1);
# open the log file
open(LOG, ">>$logfile") || die "Could not open $logfile\n";
unbuffer(\*LOG);
$branch = shift;
print "Beginning bootleg build for branch $branch\n";
writelog("Beginning bootleg build for branch $branch");
scriptRecompile() || fatal "scriptRecompile" if(!$steps[0]);
buildBootleg() || fatal "build" if(!$steps[1]);
buildPatchTree() || fatal "buildPatchTree" if(!$steps[2]);
sendBootleg() || fatal "sendBootleg" if(!$steps[3]);
installBootleg() || fatal "installBootleg" if(!$steps[4]);
testBootleg() || fatal "testBootleg" if(!$steps[5]);
email() || fatal "email" if(!$steps[6]);
upkeep() || fatal "upkeep" if(!$steps[7]);
print "Build of bootleg $newbootleg complete.\n";
writelog("Build of bootleg $newbootleg complete");
close(LOG);

View File

@@ -0,0 +1,435 @@
#! /usr/bin/perl
# ======================================================================
# ======================================================================
use warnings;
use strict;
use Socket;
# ======================================================================
# Constants
# ======================================================================
use constant START_BOOTLEG_TEST => "A";
use constant END_COMMUNICATION => "B";
use constant SUCCESSFUL_TEST => "C";
use constant UNSUCCESSFUL_TEST => "D";
use constant SERVER_READY => "E";
use constant BOOTLEG_MISMATCH => "F";
use constant CLIENT_KILL => "G";
use constant CLIENT_OK => "H";
use constant GOT_BUILD_CLUSTER_VERSION => "I";
use constant FAILED_GETTING_BUILD_CLUSTER_VERSION => "J";
use constant START_UPKEEP => "K";
use constant START_BOOTLEG_SEND => "L";
use constant BOOTLEG_SEND_DIRECTORY => "M";
use constant BOOTLEG_SEND_FILE => "N";
use constant END_BOOTLEG_SEND => "O";
use constant START_EMAIL => "P";
# ======================================================================
# Globals
# ======================================================================
my $name = $0;
$name =~ s/^(.*)\\//;
my $branch;
my $numbootlegs = 7;
my $pdbtime = 14;
my $bootlegnum = "";
my $waittime = "60";
my $port = "21498";
my $build_cluster = "lin-vthakkar.station.sony.com";
my $candela = "p:";
# ======================================================================
# Subroutines
# ======================================================================
sub usage
{
die "\n\t$name\n\n";
}
sub perforceWhere
{
local $_;
# find out where a perforce file resides on the local machine
my $result;
{
open(P4, "p4 where $_[0] |");
$_ = <P4>;
chomp;
my @where = split;
$result = $where[2];
close(P4);
}
return $result;
}
sub reloop
{
print STDERR "Error with: $_[0]\n" if(defined $_[0]);
print STDERR "Exiting this connection\n";
goto FAIL;
}
sub installBootleg
{
print "Installing bootleg...\n";
open(INSTALL, "perl " . perforceWhere("//depot/swg/current/tools/InstallBootleg.pl") . " --list --force_newest --client_only --no_database $branch |") or reloop "Error running InstallBootleg.pl\n";
my $complete = 0;
while(<INSTALL>)
{
print;
$bootlegnum = $1 if(/^Updating to build: (\d+)/);
$complete = 1 if(/^Update complete/);
}
close(INSTALL);
print "Bootleg installation incomplete\n" if(!$complete);
print "Completed installing bootleg.\n" if($complete);
return $complete;
}
sub error
{
my $message = shift @_;
print SOCKET UNSUCCESSFUL_TEST;
print STDERR "$message\n";
goto FAIL;
}
sub fatal
{
my $message = shift @_;
print SOCKET UNSUCCESSFUL_TEST;
close(SOCKET);
die "$message\n";
}
sub makeDir
{
my(@tok, $check);
@tok = split(/\\|\//, $_[0]);
$check = shift(@tok);
foreach (@tok)
{
$check .= "/$_";
if(!(-d $check))
{
mkdir $check;
}
}
}
sub recieveBootleg
{
my $buffer;
return 0 if (read(SOCKET, $buffer, 4) != 4);
my $length = unpack("N", $buffer);
return 0 if(read(SOCKET, $branch, $length) != $length);
return 0 if (read(SOCKET, $buffer, 4) != 4);
$bootlegnum = unpack("N", $buffer);
print STDERR "Recieving bootleg $branch/$bootlegnum...\n";
my $directory = "";
while(1)
{
return 0 if (read(SOCKET, $buffer, 1) != 1);
last if($buffer eq END_BOOTLEG_SEND);
if($buffer eq BOOTLEG_SEND_DIRECTORY)
{
return 0 if (read(SOCKET, $buffer, 4) != 4);
$length = unpack("N", $buffer);
return 0 if (read(SOCKET, $directory, $length) != $length);
makeDir("$candela/SWO/swg_bootleg_builds/$branch/$bootlegnum/$directory");
chdir("$candela/SWO/swg_bootleg_builds/$branch/$bootlegnum/$directory") || reloop "Cannot chdir to $branch/$bootlegnum/$directory - $!\n";
}
if($buffer eq BOOTLEG_SEND_FILE)
{
return 0 if (read(SOCKET, $buffer, 2*4) != 2*4);
my ($fileNameLength, $fileSize) = unpack("NN", $buffer);
my $localFileName;
return 0 if (read(SOCKET, $localFileName, $fileNameLength) != $fileNameLength);
print STDERR "Receiving $branch/$bootlegnum/$directory/$localFileName ($fileSize bytes)\n";
open(F, ">$localFileName") || reloop ("could not open $localFileName for writing");
chmod (0755, $localFileName);
binmode(F);
while ($fileSize)
{
my $readSize = 16 * 1024;
$readSize = $fileSize if ($fileSize < $readSize);
my $readResult = read(SOCKET, $buffer, $readSize);
reloop "socket to controller machine abruptly terminated ($fileSize bytes remained)\n" if (!defined($readResult));
reloop "read incorrect amount ($fileSize bytes remained)\n" if ($readResult == 0);
print F $buffer;
$fileSize -= $readResult;
}
endbootleginstall("copied wrong number of bytes") if ($fileSize != 0);
close(F);
}
}
chdir("$candela/SWO/swg_bootleg_builds") || reloop "Cannot chdir to $candela - $!\n";;
print STDERR "Completed recieving bootleg $branch/$bootlegnum...\n";
}
sub testBootleg
{
my $buffer;
print STDERR "Initializing communication...\n";
error("problem reading from socket") if (read(SOCKET, $buffer, 4) != 4);
my $length = unpack("N", $buffer);
error("problem reading from socket") if(read(SOCKET, $branch, $length) != $length);
print STDERR "Testing bootleg for branch: $branch\n";
my $bootlegdir = perforceWhere("//depot/swg/$branch/bootleg/win32/...");
$bootlegdir =~ s/\.{3}//;
chdir($bootlegdir) or reloop "Cannot change to bootleg directory\n";
installBootleg() || fatal "Error installing bootleg";
print SOCKET pack("N", $bootlegnum);
error("problem reading from socket") if (read(SOCKET, $buffer, 1) != 1);
error("mismatch in client / server bootlegs")if($buffer eq BOOTLEG_MISMATCH);
error("server not ready") if ($buffer ne SERVER_READY);
print STDERR "Bootleg $bootlegnum verified with server - running client...\n";
my $killresult;
my $swgpid = open(SWGCLIENT, "SwgClient_o.exe -- -s ClientGame loginServerAddress=$build_cluster skipIntro=true skipSplash=true autoConnectToLoginServer=true loginClientID=bootleg loginClientPassword=bootleg avatarName=\"bootleg bootleg\" autoConnectToGameServer=true autoQuitAfterLoadScreen=true -s SharedFoundation demoMode=true |");
error("problem reading from socket") if (read(SOCKET, $buffer, 1) != 1);
if($buffer eq CLIENT_KILL)
{
kill 1, $swgpid;
error("Test unsuccessful - forced to kill client");
}
elsif($buffer eq CLIENT_OK)
{
# make sure we give the client a chance to exit on its own, then attempt to kill
print "Waiting for $waittime seconds for the client to end on its own...\n";
sleep($waittime);
$killresult = kill 1, $swgpid;
}
close(SWGCLIENT);
# clientResult = 1 if return value of SwgClient == 0 and we did not have to kill it ($killresult = 0)
my $clientResult = (!($? >> 8) && !$killresult);
print "clientresult=$clientResult killresult=$killresult exitresult=$?\n";
print SOCKET ($clientResult == 1) ? SUCCESSFUL_TEST : UNSUCCESSFUL_TEST;
if($clientResult == 1)
{
open(BLESS, ">$candela/SWO/swg_bootleg_builds/$branch/$bootlegnum/blessed.txt");
close(BLESS);
}
print STDERR "Test was " . (($clientResult == 1) ? "successful\n" : "unsuccessful\n") . "\n";
}
sub upkeep
{
my $buffer;
return 0 if (read(SOCKET, $buffer, 4) != 4);
my $length = unpack("N", $buffer);
return 0 if(read(SOCKET, $branch, $length) != $length);
print STDERR "Performing upkeep on bootleg directory for $branch...\n";
my @bootlegs;
my $removedbootlegs = 0;
my $buildcluster;
print STDERR "Getting bootleg version on build cluster...\n";
my $controller = perforceWhere("//depot/swg/current/tools/build_cluster_controller.pl");
open(BUILD, "perl $controller -bootleg-version 2>&1 |");
while(<BUILD>)
{
$buildcluster = $1 if(/^Build cluster bootleg version is: (\d+)/);
}
close(BUILD);
if(!defined $buildcluster)
{
print STDERR "Could not get build cluster bootleg version.\n";
print SOCKET FAILED_GETTING_BUILD_CLUSTER_VERSION;
return 0;
}
else
{
print STDERR "Build cluster bootleg version is $buildcluster.\n";
print SOCKET GOT_BUILD_CLUSTER_VERSION;
print SOCKET pack("N", $buildcluster);
}
opendir DH, "$candela/SWO/swg_bootleg_builds/$branch" or fatal "Cannot open $candela/SWO/swg_bootleg_builds/$branch: $!\n";
foreach (readdir DH)
{
push @bootlegs, $_ if(/^\d+$/ && -d ("$candela/SWO/swg_bootleg_builds/$branch/$_"));
}
closedir DH;
@bootlegs = sort { $a <=> $b } @bootlegs;
while(@bootlegs > $numbootlegs)
{
my $bootleg = shift @bootlegs;
next if($buildcluster == $bootleg);
print STDERR "Removing bootleg $bootleg...\n";
system("rm -fr $candela/SWO/swg_bootleg_builds/$branch/$bootleg");
print SOCKET pack("N", $bootleg);
++$removedbootlegs;
}
print SOCKET pack("N", 0);
print STDERR "Completed upkeep on bootleg directory - removed $removedbootlegs bootlegs.\n";
my $removedpdbs = 0;
print STDERR "Performing upkeep on pdb directory...\n";
opendir DH, "$candela/SWO/pdbs" or fatal "Cannot open $candela/SWO/pdbs: $!\n";
foreach (sort readdir DH)
{
my $pdbfile = $_;
if($pdbfile =~ /^\d+_0_$branch\.zip$/ && -M "$candela/SWO/pdbs/$pdbfile" > $pdbtime)
{
print STDERR "Deleting $pdbfile...\n";
#system("rm -f $candela/SWO/pdbs/$pdbfile");
print SOCKET pack("N", length $pdbfile);
print SOCKET $pdbfile;
++$removedpdbs;
}
}
closedir DH;
print SOCKET pack("N", 0);
print STDERR "Completed upkeep on pdb directory - removed $removedpdbs pdbs.\n\n";
return 1;
}
sub endEmail
{
print SOCKET pack("N", 0);
return 0;
}
sub bootlegDirDescending
{
my($a, $b) = @_;
# Both are numbers
return $b <=> $a if($a =~ /^\d+$/ && $b =~ /^\d+$/);
# Both are not numbers
return $a cmp $b if(!($a =~ /^\d+$/) && !($b =~ /^\d+$/));
# $a is a number, $b is not
return -1 if($a =~ /^\d+$/);
# $a is not a number, $ b is
return 1;
}
sub email
{
my $currentBootleg = "";
my $oldBootleg = "";
my $buffer;
return endEmail() if(read(SOCKET, $buffer, 4) != 4);
my $currentBootlegLength = unpack("N", $buffer);
return endEmail() if($currentBootlegLength == 0);
return endEmail() if(read(SOCKET, $currentBootleg, $currentBootlegLength) != $currentBootlegLength);
opendir DH, "$candela/SWO/swg_bootleg_builds/$branch" or fatal "Cannot open $candela/SWO/swg_bootleg_builds/$branch: $!\n";
foreach (sort { bootlegDirDescending($b, $a) } readdir DH)
{
# we want the 1st blessed one that is not the one we are looking at
next if($currentBootleg eq $_);
if(/^\d+$/ && -d "$candela/SWO/swg_bootleg_builds/$branch/$_" && -f "$candela/SWO/swg_bootleg_builds/$branch/$_/blessed.txt")
{
$oldBootleg = $_;
last;
}
}
closedir DH;
print SOCKET pack("N", length $oldBootleg);
print SOCKET $oldBootleg;
print STDERR "Completed sending information to build_bootleg_linux.\n";
}
# ======================================================================
# Main
# ======================================================================
# open the daemon socket
print STDERR "Opening socket\n";
socket(LISTEN, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die "socket failed\n";
setsockopt(LISTEN, SOL_SOCKET, SO_REUSEADDR, 1) || die "setsockopt failed\n";
my $addr = sockaddr_in($port, INADDR_ANY);
bind(LISTEN, $addr) || die "bind failed\n";
listen(LISTEN, 1) || die "listen failed\n";
BUILDLOOP:
while (1)
{
print STDERR "Waiting on a connection...\n";
accept(SOCKET, LISTEN) || reloop "accept failed\n";
# make binary and unbuffer the socket
binmode(SOCKET);
my $oldSelect = select(SOCKET);
$| = 1;
select($oldSelect);
my $buffer;
error("problem reading from socket") if (read(SOCKET, $buffer, 1) != 1);
if($buffer eq START_BOOTLEG_TEST)
{
print "Got message to initiate bootleg test.\n";
testBootleg();
}
elsif($buffer eq START_UPKEEP)
{
print "Got message to perform upkeep.\n";
upkeep();
}
elsif($buffer eq START_BOOTLEG_SEND)
{
print "Got message to start recieving bootleg.\n";
recieveBootleg();
}
elsif($buffer eq START_EMAIL)
{
print "Got message to start email.\n";
email();
}
FAIL:
close(SOCKET);
}

View File

@@ -0,0 +1,744 @@
#! /usr/bin/perl
# ======================================================================
# ======================================================================
use strict;
use warnings;
use Socket;
use File::Copy;
# ======================================================================
# Constants
# ======================================================================
use constant START_COMMUNICATION => "S";
use constant START_NOT_LOCKED_READY => "B";
use constant START_LOCKED_READY => "C";
use constant START_LOCKED_READY_UNAUTHORIZED_USER => "L";
use constant START_ERROR_AUTHORIZING => "K";
use constant END_COMMUNICATION => "E";
use constant END_SUCCESSFULL => "F";
use constant SUCCESSFULL_COMMAND => "P";
use constant FAILED_COMMAND => "U";
use constant UPDATE_BOOTLEG_STEP_OK => "G";
use constant UPDATE_BOOTLEG_STEP_FAILED => "H";
use constant UPDATE_BOOTLEG_SEND_DIRECTORY => "M";
use constant UPDATE_BOOTLEG_SEND_FILE => "N";
use constant UPDATE_BOOTLEG_FILES_FINISHED => "Q";
use constant SNAPSHOT_FAILED => "O";
use constant SNAPSHOT_SUCCESSFULL => "P";
use constant COMMAND_RESTART => "a";
use constant COMMAND_RESTART_LOGIN => "b";
use constant COMMAND_RESTART_NODES => "c";
use constant COMMAND_LOCK => "d";
use constant COMMAND_UNLOCK => "e";
use constant COMMAND_UPDATE_BOOTLEG => "f";
use constant COMMAND_CONTENT_SYNC => "g";
use constant COMMAND_SYNC_SPECIFIED_CHANGELISTS => "h";
use constant COMMAND_SNAPSHOT => "i";
use constant COMMAND_BOOTLEG_VERSION => "j";
use constant COMMAND_FREE_OBJECT_IDS => "k";
# ======================================================================
# Globals
# ======================================================================
my $buildCluster = "swo-dev9.station.sony.com";
my $port = "98452";
my $candela = "p:";
my $exitcode = 0;
my $name = $0;
$name =~ s/^(.*)\\//;
my $option;
my $command;
my $user;
# ======================================================================
# Subroutines
# ======================================================================
sub usage
{
print STDERR "\nUsage:\n";
print STDERR "\t$name [command(s)]\n\n".
"\t\t-restart :\n\t\t\t restart the build cluster (central node)\n".
"\t\t-restart-login :\n\t\t\t restart the Login server\n".
"\t\t-restart-nodes :\n\t\t\t restart all nodes of the build cluster\n".
"\t\t-lock :\n\t\t\t lock the build cluster (must be authorized user)\n".
"\t\t-unlock :\n\t\t\t unlock the build cluster (must be authorized user)\n".
"\t\t-update-bootleg <branch> :\n\t\t\t update the bootleg on the build cluster (p4 key check) - needs to be run in windows\n".
"\t\t-bootleg-version:\n\t\t\t check bootleg version on the build cluster\n".
"\t\t-free-object-ids :\n\t\t\t free object IDs in the database for the build cluster\n".
"\t\t-content-sync [changelist] :\n\t\t\t shut down, content sync to specific changelist (if none, content sync to head), bring up\n".
"\t\t-sync-specified-changelists <changelist [| changelist]> :\n\t\t\t shut down, sync to multiple specified changelists, bring up\n".
"\t\t-snap <schema> <branch> [dontsubmit] :\n\t\t\t free object IDs, make a snapshot, verifies before adding files to <branch> in perforce\n\t\t\t and submits unless [dontsubmit]\n".
"\t\t\t If <schema> does not exist, it is created otherwise it is overwritten\n".
"\n\tIf multiple commands are given, the build cluster will go down / come up only once around the commands (if necessary)\n";
die "\n";
}
sub exitFailed
{
$exitcode = 1;
goto FAIL;
}
sub perforceWhere
{
local $_;
# find out where a perforce file resides on the local machine
my $result;
{
open(P4, "p4 where $_[0] |");
$_ = <P4>;
chomp;
my @where = split;
$result = $where[2];
close(P4);
}
return $result;
}
sub checkarguments()
{
my @args = @ARGV;
while(@args)
{
my $elem = shift @args;
# check if the key is valid if the command requires one
if($elem =~ /^-snap$/)
{
$elem = shift @args;
&usage() if(!(defined $elem) || $elem =~ /^-/);
$elem = shift @args;
&usage() if(!(defined $elem) || $elem =~ /^-/);
# check for optional parameter
shift @args if((defined $args[0]) && $args[0] eq "dontsubmit");
}
elsif($elem =~ /^-update-bootleg$/)
{
$elem = shift @args;
&usage() if(!(defined $elem) || $elem =~ /^-/);
}
elsif($elem =~ /^-content-sync$/)
{
shift @args if(@args && !($args[0] =~ /^-/));
}
elsif($elem =~ /^-sync-specified-changelists$/)
{
$elem = shift @args;
&usage() if(!defined $elem || $elem =~ /^-/);
while(@args)
{
last if($args[0] =~ /^-/);
shift @args;
}
}
elsif(!($elem =~ /^-restart$/ || $elem =~ /^-restart-login$/ || $elem =~ /^-restart-nodes$/ || $elem =~ /^-lock$/ || $elem =~ /^-unlock$/ || $elem =~ /^-bootleg-version$/ || $elem =~ /^-free-object-ids$/ || $elem =~ /^-build_script_publish$/))
{
&usage();
}
}
}
sub openbuildsocket
{
socket(BUILD, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die "socket failed\n";
{
my $destination = inet_aton($buildCluster) || die "inet_aton failed\n";
my $paddr = sockaddr_in($port, $destination);
connect(BUILD, $paddr) || die "connect failed\n";
# unbuffer the socket
my $oldSelect = select(BUILD);
$| = 1;
select($oldSelect);
# put the socket into binary mode
binmode BUILD;
}
}
sub getuser
{
my $user;
open(P4, "p4 user -o |") || die "p4 user failed\n";
while(<P4>)
{
$user = $1 if(/^User:\s+(\S+)/);
}
close(P4);
die "Could not get perforce user\n" if(!defined $user);
return $user;
}
sub sendstartinfo
{
print STDERR "Contacting build cluster...\n";
print BUILD START_COMMUNICATION;
my $initializer = $user;
$initializer = "buildscript" if($user eq "build_script_publish");
my $length = length $initializer;
print BUILD pack("N", $length);
print BUILD $initializer;
my $returncode;
if(read(BUILD, $returncode, 1) != 1)
{
print STDERR "Problem contacting build server\n";
return 0;
}
if($returncode eq START_NOT_LOCKED_READY)
{
print STDERR "Build server is not locked and ready\n\n";
return 1;
}
elsif($returncode eq START_LOCKED_READY)
{
print STDERR "Build server is locked and ready\n\n";
return 1;
}
elsif($returncode eq START_LOCKED_READY_UNAUTHORIZED_USER)
{
print STDERR "Build server is locked (limited access for non-authoritative user)\n\n";
return 1;
}
elsif($returncode eq START_ERROR_AUTHORIZING)
{
print STDERR "problem authorizing $user for build server\n\n";
return 0;
}
else
{
print STDERR "Build server not ready\n\n";
return 0;
}
}
sub sendendinfo
{
print STDERR "Ending communication with build cluster...\n";
print BUILD END_COMMUNICATION;
my $returncode;
my $readreturn = read(BUILD, $returncode, 1);
if(!defined $readreturn || $readreturn != 1)
{
print STDERR "Build server communication ended abruptly\n";
return 0;
}
if($returncode eq END_SUCCESSFULL)
{
print STDERR "Build server communication ended successfully\n";
return 1;
}
else
{
print STDERR "Build server communication ended with errors\n";
return 0;
}
}
sub contentsync
{
my $changelist = "";
$changelist = shift @ARGV if(@ARGV && !($ARGV[0] =~ /^-/));
my $length = length $changelist;
print BUILD pack("N", $length);
print BUILD $changelist;
# Recieve any errors from the content sync
my $buffer;
return 0 if(read(BUILD, $buffer, 4) != 4);
$length = unpack("N", $buffer);
return 0 if(read(BUILD, $buffer, $length) != $length);
print $buffer;
return 1;
}
sub syncspecifiedchangelists
{
my $changelists = "";
while(@ARGV)
{
last if($ARGV[0] =~ /^-/);
my $elem = shift @ARGV;
$changelists .= "$elem ";
}
chomp $changelists;
if($changelists eq "")
{
print BUILD pack("N", 0);
print STDERR "You must specify changelist\(s\)\n";
return 0;
}
my $length = length $changelists;
print BUILD pack("N", $length);
print BUILD $changelists;
return 1;
}
sub endsubmit
{
print "Error running: $_[0]\n";
return 0;
}
sub submitopenfiles
{
my $dontsubmit = shift;
local $_;
my @files;
system("p4 revert -a > /dev/null");
open(P4, "p4 -ztag opened -c default |");
while (<P4>)
{
chomp;
push (@files, $_) if (s/^\.\.\. depotFile //);
}
close(P4);
if(!@files)
{
print STDERR "No changed files, nothing to submit\n";
return 1;
}
my $tmpfile = "submit.tmp";
# submit all the open files
open(TMP, ">" . $tmpfile);
print TMP "Change:\tnew\n";
print TMP "\nDescription:\n";
foreach (@_)
{
print TMP "\t", $_, "\n";
}
print TMP "\nFiles:\n";
foreach (@files)
{
print TMP "\t", $_, "\n";
}
close(TMP);
if ($dontsubmit)
{
open(P4, "p4 change -i < $tmpfile |") || return 0;
while(<P4>)
{
print STDERR "Successfully created changelist $1\n" if(/Change (\d+) created/);
}
close(P4);
}
else
{
open(P4, "p4 submit -i < $tmpfile |") || return 0;
while(<P4>)
{
print STDERR "Successfully submitted at changelist $1\n" if(/Change (\d+) submitted/);
}
close(P4);
}
return 0 if ($? != 0);
unlink($tmpfile);
return 1;
}
sub snapshot
{
my $dbSchema = shift @ARGV;
my $branch = shift @ARGV;
my $dontsubmit = 0;
my $snapshotLog = "";
my $buffer = "";
my $p4operation = "submit";
if (defined($ARGV[0]) && $ARGV[0] eq "dontsubmit")
{
$dontsubmit = 1;
$p4operation = "change";
shift @ARGV;
}
print BUILD pack("N", length $dbSchema);
print BUILD $dbSchema;
if(read(BUILD, $buffer, 1) != 1 || $buffer eq SNAPSHOT_FAILED)
{
print STDERR "Snapshot not created successfully on the build cluster\n";
return 0;
}
# Recieve files
my @worldSnapshots;
print STDERR "Snapshot generation complete.\n";
while(1)
{
return 0 if (read(BUILD, $buffer, 2*4) != 2*4);
my ($fileSize, $fileNameLength) = unpack("NN", $buffer);
# check if we are finished
last if($fileSize == 0 && $fileNameLength == 0);
my $localFileName;
return 0 if (read(BUILD, $localFileName, $fileNameLength) != $fileNameLength);
# first file sent will be the snapshot log
$snapshotLog = $localFileName if($snapshotLog eq "");
# add all ws files to the array
push @worldSnapshots, $localFileName if($localFileName =~ /\.ws$/);
# receive the binary bits for the file
print STDERR "Receiving $localFileName ($fileSize bytes)...";
unlink $localFileName;
open(F, ">" . $localFileName) || return endbootleginstall("could not open $localFileName for writing");
binmode(F);
while ($fileSize)
{
my $readSize = 16 * 1024;
$readSize = $fileSize if ($fileSize < $readSize);
my $readResult = read(BUILD, $buffer, $readSize);
return 0 if (!defined($readResult));
return 0 if ($readResult == 0);
print F $buffer;
$fileSize -= $readResult;
}
return 0 if ($fileSize != 0);
close(F);
print "done\n";
}
# Echo log to user
print STDERR "--- Start of snapshot log:\n";
system("cat $snapshotLog") == 0 || return 0;
print STDERR "--- End of snapshot log:\n";
# Only verify using STDIN if we are not being called by the build script
if($user ne "build_script_publish")
{
print STDERR "\nAre the world snapshots ok to do perforce $p4operation? (y/n)\n";
while(<STDIN>)
{
chomp;
if($_ eq "y" || $_ eq "Y")
{
last;
}
elsif($_ eq "n" || $_ eq "N")
{
return 1;
}
print STDERR "Please enter \'y\' or \'n\'\n";
}
}
# If we get here, we have decided to submit
print STDERR "Proceeding with $p4operation\n";
# Get a hash of the current world snapshots in perforce
my %ws;
open(FILES, "p4 files //depot/swg/$branch/data/sku.0/sys.client/built/game/snapshot/... |") || return endsubmit("p4 files");
while(<FILES>)
{
$ws{$1} = 1 if(/\/([^\/]+\.ws)#/);
}
close(FILES);
# Edit files and move to appropriate directory
system("p4 edit //depot/swg/$branch/data/sku.0/sys.client/built/game/snapshot/...") == 0 || return endsubmit("p4 edit snapshot dir");
foreach(@worldSnapshots)
{
system("p4 add //depot/swg/$branch/data/sku.0/sys.client/built/game/snapshot/$_") == 0 || return endsubmit("p4 add") if(!exists($ws{$_}));
copy($_, perforceWhere("//depot/swg/$branch/data/sku.0/sys.client/built/game/snapshot/$_")) || return endsubmit("moving *.ws to snapshot dir");
}
system("p4 edit //depot/swg/$branch/dsrc/sku.0/sys.client/built/game/snapshot/swg_object.txt") == 0 || return endsubmit("p4 edit swg_object.txt");
copy("swg_object.txt", perforceWhere("//depot/swg/$branch/dsrc/sku.0/sys.client/built/game/snapshot/swg_object.txt")) || return endsubmit("moving object file to swg_object.txt");
# create golddata text file
createGoldDataFile($dbSchema, $branch);
submitopenfiles($dontsubmit, "[automated]", "New snapshots for $branch from build_cluster_controller ($dbSchema)") || return endsubmit("p4 $p4operation");
return 1;
}
sub createGoldDataFile
{
my ($dbSchema, $branch) = @_;
my $goldDataFile = perforceWhere("//depot/swg/$branch/src/game/server/database/build/linux/golddata.txt");
system("p4 edit $goldDataFile");
open(GOLDDATA, "> $goldDataFile");
print GOLDDATA "$dbSchema\n";
close GOLDDATA;
system("p4 add $goldDataFile");
}
sub getbootlegversion
{
my $buffer;
return 0 if(read(BUILD, $buffer, 4) != 4);
my $length = unpack("N", $buffer);
return 0 if(read(BUILD, $buffer, $length) != $length);
if($length == 0)
{
print STDERR "Could not get build cluster bootleg version\n";
return 0;
}
print STDERR "Build cluster bootleg version is: $buffer\n";
return 1;
}
sub updatebootleg
{
my $branch = shift @ARGV;
# Get the number of the most recent bootleg
my $dir = "$candela/swo/builds/$branch";
my $buffer;
my $change = 0;
opendir DH, $dir or return 0;
foreach (readdir DH)
{
$change = $_ if(/^\d+$/ && -d ($dir."/".$_) && $_ > $change);
}
closedir DH;
return 0 if(!$change);
print STDERR "Most recent blessed bootleg is: $change\n";
# Send info to build cluster
print STDERR "Syncing build cluster to $change...\n";
print BUILD pack("N", $change);
return 0 if(read(BUILD, $buffer, 1) != 1 || $buffer ne UPDATE_BOOTLEG_STEP_OK);
print STDERR "Sync of build cluster complete.\n";
# Compress the server binaries
my $file = "servers_debug.tar.gz";
print STDERR "Compressing server binaries...\n";
system("tar --create --gzip --directory=$dir/$change/servers_debug --file=/tmp/$file .") == 0 || die "Failed to compress $dir/$change/servers_debug";
print STDERR "Compress server binaries complete.\n";
# Send file to build cluster
die "Can't find server zip file!\n" if (!-s "c:/cygwin/tmp/$file");
my $fileSize = -s "c:/cygwin/tmp/$file";
print STDERR "Sending file $file ($fileSize bytes)\n";
print BUILD pack("NN", $fileSize, length $file);
print BUILD $file;
open(F, "<c:/cygwin/tmp/$file");
binmode(F);
while ($fileSize)
{
my $buffer;
my $readSize = 16 * 1024;
$readSize = $fileSize if ($fileSize < $readSize);
my $readResult = read(F, $buffer, $readSize);
die "unexpected end of file" if (!defined($readResult));
die "did not read what we expected to" if ($readResult != $readSize);
print BUILD $buffer;
$fileSize -= $readResult;
}
die "copied all the bytes but not at EOF" if (!eof(F));
close(F);
# Cleanup
unlink "c:/cygwin/tmp/$file";
if(read(BUILD, $buffer, 1) != 1 || $buffer ne UPDATE_BOOTLEG_STEP_OK)
{
print "Failed while sending file.\n";
closedir DH;
return 0;
}
print "$file sent.\n";
print STDERR "Updating database on build cluster...\n";
return 0 if(read(BUILD, $buffer, 1) != 1 || $buffer ne UPDATE_BOOTLEG_STEP_OK);
print STDERR "Database update on build cluster complete.\n";
print STDERR "Syncing individual changelists on build cluster...\n";
my @syncChangelists;
open(SYNC, "$candela/SWO/builds/$branch/$change/sync.txt") || return 0;
while(<SYNC>)
{
chomp;
push @syncChangelists, $_;
}
close(SYNC);
print BUILD pack("N", length (join(" ", @syncChangelists)));
print BUILD join(" ", @syncChangelists);
return 0 if(read(BUILD, $buffer, 1) != 1 || $buffer ne UPDATE_BOOTLEG_STEP_OK);
print STDERR "Inidividual changelist sync complete.\n";
return 1;
}
# ======================================================================
# Main
# ======================================================================
&usage if(@ARGV == 0);
# Check to see if we're testing
if($ARGV[0] eq "vthakkar-box")
{
shift;
$buildCluster = "lin-vthakkar.station.sony.com";
}
$user = getuser();
$user = "build_script_publish" if(grep("-build_script_publish" eq $_, @ARGV));
checkarguments();
openbuildsocket();
sendstartinfo() || exitFailed();
while(@ARGV)
{
$option = shift @ARGV;
if($option eq "-restart")
{
print STDERR "Restarting build cluster...\n";
print BUILD COMMAND_RESTART;
}
elsif($option eq "-restart-login")
{
print STDERR "Restarting loginserver on build cluster...\n";
print BUILD COMMAND_RESTART_LOGIN;
}
elsif($option eq "-restart-nodes")
{
print STDERR "Restarting build cluster nodes...\n";
print BUILD COMMAND_RESTART_NODES;
}
elsif($option eq "-lock")
{
print STDERR "Locking build cluster...\n";
print BUILD COMMAND_LOCK;
}
elsif($option eq "-unlock")
{
print STDERR "Unlocking build cluster...\n";
print BUILD COMMAND_UNLOCK;
}
elsif($option eq "-update-bootleg")
{
print STDERR "Updating bootleg on build cluster...\n";
print BUILD COMMAND_UPDATE_BOOTLEG;
updatebootleg() || goto ERROR;
}
elsif($option eq "-content-sync")
{
print STDERR "Content syncing build cluster...\n";
print BUILD COMMAND_CONTENT_SYNC;
contentsync() || goto ERROR;
}
elsif($option eq "-sync-specified-changelists")
{
print STDERR "Syncing build cluster to changelists...\n";
print BUILD COMMAND_SYNC_SPECIFIED_CHANGELISTS;
syncspecifiedchangelists() || goto ERROR;
}
elsif($option eq "-snap")
{
print STDERR "Creating snapshot on build cluster...\n";
print BUILD COMMAND_SNAPSHOT;
snapshot() || goto ERROR;
}
elsif($option eq "-bootleg-version")
{
print STDERR "Checking bootleg version on build cluster...\n";
print BUILD COMMAND_BOOTLEG_VERSION;
getbootlegversion() || goto ERROR;
}
elsif($option eq "-free-object-ids")
{
print STDERR "Freeing object ids on build cluster...\n";
print BUILD COMMAND_FREE_OBJECT_IDS;
}
elsif($option eq "-build_script_publish")
{
next;
}
else
{
print STDERR "Error: cannot decipher option: $option\n";
goto FAIL;
}
ERROR:
my $success;
exitFailed() if(!read(BUILD, $success, 1));
if($success eq SUCCESSFULL_COMMAND)
{
print STDERR "Successfully completed $option\n\n";
}
else
{
print STDERR "Error encountered while running $option\n\n";
exitFailed();
}
}
FAIL:
sendendinfo();
close(BUILD);
exit($exitcode);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
#!/usr/bin/perl
# Given a planet name, searches a log file to check that every chunk on that planet was loaded
($targetPlanet, $logfile)=@ARGV;
open(LOGFILE,$logfile);
while (<LOGFILE>)
{
if (/ChunkLocator:Chunk (\w+) ([-\d]+) ([-\d]+)/)
{
($planet, $x, $z) = ($1, $2, $3);
if ($planet eq $targetPlanet)
{
$chunks{$x.":".$z}+=1;
}
}
}
for ($x=-8000; $x<=8000; $x+=100)
{
for ($z=-8000; $z<=8000; $z+=100)
{
if ($chunks{$x.":".$z}!=2)
{
print "Chunk error $targetPlanet $x,$z. Was in logs ".($chunks{$x.":".$z}+0)." times (should be 2 times)\n";
}
}
}

View File

@@ -0,0 +1,54 @@
# ================================================================================
#
# checkCreatureStrings.pl
# Copyright 2006, Sony Online Entertainment LLC
#
# ================================================================================
use Cwd;
# --------------------------------------------------------------------------------
die "usage: $0\n\t Checks that all creatures.tab creature names are localized. Outputs missing creature names." if (@ARGV);
die "Must be run within a swg directory!" if (getcwd() !~ m!(.*/swg/\w+/)!);
my $rootPath = $1;
my $creaturesStringFile = "data/sku.0/sys.shared/built/game/string/en/mob/creature_names.stf";
my $creaturesTabFile = "dsrc/sku.0/sys.server/compiled/game/datatables/mob/creatures.tab";
my $localizationToolCon = "../all/tools/all/win32/LocalizationToolCon_r.exe";
# --------------------------------------------------------------------------------
open(CS, "$rootPath$localizationToolCon $rootPath$creaturesStringFile -list |") || die "$!";
while (<CS>)
{
split;
$creaturesString{$_[0]} = 1;
}
close(CS);
open(CT, "$rootPath$creaturesTabFile") || die "$!";
<CT>; <CT>; # skip column header name & type
while (<CT>)
{
split;
if (!$creaturesString{$_[0]})
{
print "$_[0]\n";
++$missingStringCount;
}
}
close(CT);
if ($missingStringCount)
{
print STDERR "\nFAILURE! Missing $missingStringCount creature name strings!\n";
}
else
{
print STERR "\nSUCCESS! No missing creature strings!\n";
}
exit $missingStringCount;
# ================================================================================

View File

@@ -0,0 +1,70 @@
#!/usr/bin/perl -w
use File::Find;
use BuildFunctions;
##
# This subroutine finds any non-authorized writable files in a passed directory
sub Find_Writable
{
if (-d $_)
{
# found a directory entry
# prune the directory if it's one we want to ignore
if (m/^(compile)$/)
{
#prune it
$File::Find::prune = 1;
}
}
elsif (-f and -w $_)
{ if (!m/^.*(aps|ncb|opt|plg)$/)
{
print "n $File::Find::name\n";
print Logfile "n $File::Find::name\n";
}
}
} # End of sub Find_Writable
########## MAIN ##########
# Email addresses
$gmcdaniel = "gmcdaniel\@soe.sony.com";
##
# Check for any non-authorized writable files in the /swg/current/src directory and email the results
$writable_files_log = "WritableFiles.log";
print ("Checking for writable files...\n");
open (Logfile, ">c:\\buildlogs\\$writable_files_log") || die "Sorry, I couldn't create $writable_files_log";
print Logfile "The writable files that were found:\n";
# do a find
$search_path = "..\\src";
@ARGV = ($search_path);
find(\&Find_Writable, @ARGV);
close (Logfile);
$writable_test_time_and_date = get_time_and_date();
$date_stamp = get_date();
system ("copy c:\\buildlogs\\$writable_files_log c:\\buildlogs\\WritableFiles_$writable_test_time_and_date.log");
print ("Checking for writable files completed\n");
print ("\n");
print ("\n");
system ("postie -host:mail-sd.station.sony.com -to:$gmcdaniel -from:$gmcdaniel -s:\"Writable Files Results $date_stamp\" -nomsg -file:c:\\buildlogs\\WritableFiles_$writable_test_time_and_date.log");
#
## End of Check for any non-authorized writable files in the /swg/current/src directory and email the results
########## END OF MAIN ##########

View File

@@ -0,0 +1,84 @@
#!/usr/bin/perl
# Script to test the environment for a server
# Looks at enviroment variables, etc., to make
# sure everything is installed
&checkJava;
&checkOracle;
&summary;
sub checkJava
{
$ldpath=$ENV{"LD_LIBRARY_PATH"};
if (!($ldpath =~ /java/))
{
&error("Java must be in LD_LIBRARY_PATH.\n");
}
}
# Check the oracle installation
# Note: May need to change the name of the database to
# match whatever the production database gets called.
sub checkOracle
{
$ldpath=$ENV{"LD_LIBRARY_PATH"};
if (!($ldpath =~ /oracle/))
{
&error("\$ORACLE_HOME/lib must be in LD_LIBRARY_PATH.\n");
}
$oracleHome=$ENV{"ORACLE_HOME"};
if ($oracleHome eq "")
{
&error("ORACLE_HOME is not set. Remaining Oracle tests skipped.\n");
}
else
{
open (TESTCASE,"sqlplus buildcluster/changeme\@swodb < oracletest.sql 2>&1|");
while (<TESTCASE>)
{
# print;
if (/ERROR/)
{
$_=<TESTCASE>;
if (/12154/) # could not resolve service name
{
&error ("swodb service is not set up in \$ORACLE_HOME/network/admin/tnsnames.ora\n");
}
elsif (/01017/)
{
&error ("Invalid username or password for Oracle. Check that the swodb service in \$ORACLE_HOME/network/admin/tnsnames.ora is pointing to the correct database server.\n");
}
else
{
&error ("Oracle error: $_\n");
}
}
if (/command not found/)
{
&error ("\$ORACLE_HOME/bin is not in the path.\n");
}
}
}
}
# Display an error message and count the number of errors
sub error
{
my ($message) = @_;
print STDERR $message;
++$errorCount;
}
sub summary
{
if ($errorCount == 0)
{
print "No problems detected.\n";
}
else
{
die "$errorCount problem(s) detected.\n";
}
}

View File

@@ -0,0 +1,183 @@
# ======================================================================
# collectAssetCustomizationInfo.pl
# Copyright 2003, Sony Online Entertainment, Inc.
# All rights reserved.
# ======================================================================
use strict;
use AppearanceTemplate;
use BlueprintTextureRendererTemplate;
use ComponentAppearanceTemplate;
use CustomizableShaderTemplate;
use CustomizationVariableCollector;
use DetailAppearanceTemplate;
use LightsaberAppearanceTemplate;
use LodMeshGeneratorTemplate;
use MeshAppearanceTemplate;
use PortalAppearanceTemplate;
use SkeletalAppearanceTemplate;
use SkeletalMeshGeneratorTemplate;
use SwitchShaderTemplate;
use TreeFile;
use VehicleCustomizationVariableGenerator;
# ======================================================================
my $branch = "current";
my $debug = 0;
my $treeFileLookupDataFile;
# ======================================================================
sub printUsage
{
print "Usage:\n";
print "\tperl collectAssetCustomizationInfo.pl [-d] [-h] [-b <branch>] -t <treefile lookup filename>\n";
print "\n";
print "-d: if specified, turns on debugging info (Default: off)\n";
print "-h: print this help\n";
print "-t: loads the TreeFile lookup data from the specified filename\n";
}
# ----------------------------------------------------------------------
sub processCommandLineArgs
{
my $printHelp = 0;
my $requestedHelp = 0;
# Grab options from commandline.
while ((scalar @_) && !$printHelp)
{
if ($_[0] =~ m/^-h/)
{
$printHelp = 1;
$requestedHelp = 1;
}
elsif ($_[0] =~ m/^-b/)
{
shift;
$branch = $_[0];
if (!defined($branch))
{
print "User must specify a branch name after the -t option, printing help.\n";
$printHelp = 1;
}
else
{
print "\$branch=[$branch]\n" if $debug;
}
}
elsif ($_[0] =~ m/^-d/)
{
$debug = 1;
}
elsif ($_[0] =~ m/^-t/)
{
shift;
$treeFileLookupDataFile = $_[0];
if (!defined($treeFileLookupDataFile))
{
print "User must specify a treefile lookup data filename after the -t option, printing help.\n";
$printHelp = 1;
}
else
{
print "\$treeFileLookupDataFile=[$treeFileLookupDataFile]\n" if $debug;
}
}
else
{
print "Unsupported option [$_[0]], printing help.\n";
$printHelp = 1;
}
# Shift past current argument.
shift;
}
# Check if we're missing anything required.
if (!$requestedHelp)
{
if (!defined($treeFileLookupDataFile))
{
print "No TreeFile lookup data file specified, printing usage info.\n";
$printHelp = 1;
}
}
if ($printHelp)
{
printUsage();
exit ($requestedHelp ? 0 : -1);
}
}
# ----------------------------------------------------------------------
sub initialize
{
# Initialize data handlers.
&AppearanceTemplate::install();
&BlueprintTextureRendererTemplate::install();
&ComponentAppearanceTemplate::install();
&CustomizableShaderTemplate::install();
&DetailAppearanceTemplate::install();
&LightsaberAppearanceTemplate::install();
&LodMeshGeneratorTemplate::install();
&MeshAppearanceTemplate::install();
&PortalAppearanceTemplate::install();
&SkeletalAppearanceTemplate::install();
&SkeletalMeshGeneratorTemplate::install();
&SwitchShaderTemplate::install();
&VehicleCustomizationVariableGenerator::install();
# Open the TreeFile lookup datafile.
my $dataFileHandle;
die "Failed to open [$treeFileLookupDataFile]: $!" unless open($dataFileHandle, "< " . $treeFileLookupDataFile);
# Initialize the treefile.
TreeFile::loadFileLookupTable($dataFileHandle);
# Close the TreeFile lookup datafile.
die "Failed to close [$treeFileLookupDataFile]: $!" unless close($dataFileHandle);
}
# ======================================================================
# Main Program
# ======================================================================
# Handle command line.
processCommandLineArgs(@ARGV);
# Initialize subsystems (e.g. TreeFile)
initialize();
# Setup the list of patterns to match against
# TreeFile-relative filenames. Any files in the TreeFile system
# that match one of these patterns will be processed by the
# CustomizationVariableCollector.
my @processFilePatterns =
(
'^texturerenderer/.+\.trt$', '^shader/.+\.sht$',
'^appearance/.+\.(apt|cmp|lmg|lod|lsb|mgn|msh|sat|pob)$'
# ---
# TEST ENTRIES: don't include these for real processing, used to test formats one-at-a-time.
# ---
# '^appearance/.+\.sat$'
# '^appearance/.+\.mgn$'
# '^shader/.+\.sht$'
# '^appearance/.+\.lsb$'
# '^appearance/.+\.lod$'
# '^appearance/.+\.apt$'
# '^appearance/.+\.msh$'
# '^appearance/.+\.cmp$'
# ---
);
CustomizationVariableCollector::collectData(@processFilePatterns);
# Handle vehicle customization steps that cannot be handled by analyzing IFF file contents.
VehicleCustomizationVariableGenerator::collectData($branch);

View File

@@ -0,0 +1,18 @@
while (<>)
{
next if (s/^cfg: // == 0);
chomp;
($section, $value) = /\[(.*)\] (.*)/;
$key{$section . "." . $value} = 1;
}
foreach (sort keys %key)
{
($section, $value) = split(/\./, $_, 2);
if ($section ne $oldSection)
{
$oldSection = $section;
print "[", $section, "]\n";
}
print "\t", $value, "\n";
}

View File

@@ -0,0 +1,220 @@
#!/bin/bash -f
if [ $# != 4 ]; then
echo Usage: coreMemoryReport.sh exename corename dumpname reportname
exit 1
fi
checkTool()
{
which $1 >& /dev/null
if [ $? = 1 ]; then
echo "Could not find $1 in $PATH."
exit 1
fi
}
# check for needed tools
checkTool grep
checkTool sed
checkTool sort
checkTool uniq
checkTool gawk
checkTool objdump
checkTool addr2line
checkTool CoreMemWalker
# check gawk version, need >= 3.1 for coprocesses
awk_major=`gawk --version |grep '^GNU Awk' |sed -e '/^GNU Awk /s///' -e '/\..*$/s///'`
awk_minor=`gawk --version |grep '^GNU Awk' |sed -e '/^GNU Awk [0-9]*\./s///' -e '/\..*$/s///'`
if [ $awk_major -le 3 ]; then
if [ $awk_major -lt 3 ] || [ $awk_minor -lt 1 ]; then
echo 'GNU Awk version >= 3.1 is required.'
exit 1
fi
fi
EXE=$1
CORE=$2
DUMPNAME=$3
REPORTNAME=$4
# load the memory map for a specified object file and section type
loadMemoryMap()
{
objdump -h $1 |grep $2 >.tmpmem
ao_c=0
while read -a LINE ; do
let s=0x${LINE[3]}
let e=$s+0x${LINE[2]}
let o=0x${LINE[5]}-$s
ao_s[$ao_c]=$s
ao_e[$ao_c]=$e
ao_o[$ao_c]=$o
let ao_c=$ao_c+1
done <.tmpmem
}
# determine the offset in the file associated with the current memory map of the memory address passed in
getAddrOffset()
{
result=0
let t=$1
i=0
while [ $i -lt $ao_c ]; do
if [ $t -ge ${ao_s[$i]} ] && [ $t -lt ${ao_e[$i]} ] ; then
let result=${ao_o[$i]}+$t
break
fi
let i=$i+1
done
echo $result
}
# determine the object to search for memory manager info
MEMOBJ=`ldd $EXE |grep libsharedMemoryManager.so |sed 's/[()]//g' |gawk '{print $3}'`
if [ "$MEMOBJ" = "" ]; then
MEMOBJ=$EXE
MEMOFS=0
else
LINE=(`ldd $EXE |sed 's/[()]//g' |sort -k 4,4 |nl |gawk '{print $1, $4}' |grep libsharedMemoryManager.so`)
MEMOFS=0x`objdump -h $CORE |grep -B1 'READONLY, CODE' |grep '00000000 4' |nl |grep "^ *${LINE[0]} " |gawk '{print $5}'`
fi
# grab the mappings of memory regions in the memory manager object
echo Getting memory manager object memory map...
loadMemoryMap $MEMOBJ rodata
# determine the number of entries in the memory block call stacks
echo Determining memory block owner call stack size...
LINE=(`objdump -t $MEMOBJ |grep ' _[^G]*22MemoryManagerNamespace.*cms_allocatedBlockSize'`)
offset=`getAddrOffset 0x${LINE[0]}`
LINE=(`od -t x4 -j$offset -N4 $MEMOBJ`)
let own_size=(0x${LINE[1]}-12)/4
# grab the mappings of memory regions in the core file
echo Getting core memory map...
loadMemoryMap $CORE load
# get the address of the first memory block
echo Finding first memory block...
LINE=(`objdump -t $MEMOBJ |grep '22MemoryManagerNamespace.*ms_firstSystemAllocation'`)
let adjustedOfs=0x${LINE[0]}+$MEMOFS
offset=`getAddrOffset $adjustedOfs`
LINE=(`od -t x4 -j$offset -N4 $CORE`)
let firstAddr=0x${LINE[1]}
rm -f $DUMPNAME
echo Dumping allocated block info...
CoreMemWalker $CORE .tmpmem $firstAddr $own_size >$DUMPNAME
rm -f .tmpmem
echo Processing memory report...
cat $DUMPNAME |sed 's/^0x[0-9a-f]* //' |sort -n |uniq -c | \
gawk '
{
printf "%d %d", $1*$2, $1
for (i = 3; i <= NF; ++i)
printf " %s", $i
printf "\n"
}' | sort -n -r >.tmpdmp
rm -f .tmpresolve .tmplib*
# Determine all binaries associated with $EXE, and store their names and
# base addresses in the lib_name and lib_addr arrays respectively.
echo Determining address spaces...
lib_count=1
lib_addr[0]=0
lib_name[0]=$EXE
ldd $EXE |sed 's/[()]//g' |sort -k 4,4 |nl |gawk '{print $1, $4}' >.tmplibs
while read -a LINE ; do
lib_name[$lib_count]=${LINE[1]}
let lib_addr[$lib_count]=0x`objdump -h $CORE |grep -B1 'READONLY, CODE' |grep '00000000 4' |nl |grep "^ *${LINE[0]} " |gawk '{print $5}'`
let lib_count=$lib_count+1
done <.tmplibs
# Determine which library in the lib_name/lib_addr arrays the passed in
# address belongs to. Return the index in the array.
getLibNumber()
{
result=0
let t=$1
j=1
while [ $j -lt $lib_count ]; do
if [ ${lib_addr[$j]} -gt $t ] ; then
break
fi
let j=$j+1
done
let result=$j-1
echo $result
}
# Run through all referenced addresses, sorting them by the binary they
# belong to, and saving a file of addresses and a separate file of
# addresses relative to the binary's start address. Also fill in '??:0'
# in the resolved address cache for each address, so that every referenced
# address has an entry, and use that to prevent trying to resolve an
# address multiple times (by outputting duplicates to the per-binary
# address list files).
echo Sorting addresses by lib...
while read -a LINE ; do
# run through $LINE[2..] accumulating addresses per lib
i=2
while [ $i -lt ${#LINE[*]} ]; do
addr=${LINE[$i]}
if [ "${addr_cache[$addr]}" != "??:0" ] ; then
lib_number=`getLibNumber $addr`
let offset=addr-${lib_addr[$lib_number]}
echo $addr >> .tmplib_addr_$lib_number
echo -n "0x" >> .tmplib_ofs_$lib_number
echo "obase=16; $offset" |bc >> .tmplib_ofs_$lib_number
addr_cache[$addr]="??:0"
fi
let i=$i+1
done
done <.tmpdmp
# Resolve all addresses referenced in the report, batched by which binary
# the address belongs to.
echo Resolving Addresses...
i=0
while [ $i -lt $lib_count ]; do
if [ -e .tmplib_ofs_$i ]; then
addr2line -s -e ${lib_name[$i]} `cat .tmplib_ofs_$i` >.tmpresolve
j=0
while read -a LINE ; do
resolved[$j]=${LINE[*]}
let j=$j+1
done <.tmpresolve
j=0
while read -a LINE ; do
addr_cache[${LINE[*]}]=${resolved[$j]}
let j=$j+1
done <.tmplib_addr_$i
fi
let i=$i+1
done
# Generate the final report file, by looking up all but the first 2 fields of
# everything in .tmpdmp in the resolved address cache.
echo Generating Report...
rm -f $REPORTNAME
while read -a LINE ; do
echo -n "${LINE[0]} ${LINE[1]}" >> $REPORTNAME
i=2
while [ $i -lt ${#LINE[*]} ]; do
addr=${LINE[$i]}
echo -n " ${addr_cache[$addr]}($addr)" >> $REPORTNAME
let i=$i+1
done
echo >> $REPORTNAME
done <.tmpdmp
rm -f .tmpdmp .tmpresolve .tmplib*
echo Done!

View File

@@ -0,0 +1,89 @@
#!/usr/bin/perl
die "usage: coremail.pl original_core_directory save_core_directory email_to [... email_to]\n" if (@ARGV < 3);
$coreDirectory = shift;
$saveDirectory = shift;
# pick a name for the backup file
open(DATE, "date \"+%Y%m%d_%H%M\" |");
$date = <DATE>;
chomp $date;
close(DATE);
# make the destination directory
mkdir($saveDirectory);
# search for new core files
$cores = 0;
opendir(DIR, $coreDirectory) || die "could not open directory $_\n";
@files = readdir(DIR);
closedir(DIR);
foreach (@files)
{
if (/core\./)
{
$cores += 1;
$new = $_;
$new =~ s/\./\.$date\./;
system("mv $coreDirectory/$_ $saveDirectory/$new");
$exe = "";
# open(GDB1, "gdb -batch -c $saveDirectory/$new |");
# while (<GDB1>)
# {
# chomp;
# $exe = $_ if (s/^Core was generated by \`// && s/ .*//);
# }
# close(GDB1);
# push(@cores, "$saveDirectory/$new\t$exe\n");
# if ($exe ne "")
# {
# open(BT, ">/tmp/gdb.bt");
# print BT "bt\n";
# close(BT);
# open(GDB2, "gdb $coreDirectory/$exe $saveDirectory/$new -batch -x /tmp/gdb.bt |");
# while (<GDB2>)
# {
# push(@cores, "\t" . $_);
# }
# close(GDB2);
# unlink("/tmp/gdb.bt");
# }
# else
# {
# open(FILE, "file $saveDirectory/$new |");
# close(FILE);
# while (<FILE>)
# {
# push(@cores, "\t" . $_);
# }
# close(FILE);
# }
system("gzip $saveDirectory/$new");
}
}
# send out mail if necessary
if ($cores)
{
# get the host name
open(HOSTNAME, "hostname -s |");
$hostname = <HOSTNAME>;
close(HOSTNAME);
chomp $hostname;
# send the email
$s = "";
$s = "s" if ($cores > 1);
open(MAIL, "| mail -s \"[cores] $hostname has $cores new core file$s\" " . join(" ", @ARGV), );
print MAIL join("", @cores);
close(MAIL);
}

View File

@@ -0,0 +1,97 @@
#!/usr/bin/perl -w
use strict;
my (%keys, %rows);
my (@files, $file);
my $row = 0;
my $spaced = 0;
die "$0: Usage: $0 <directory>\n" unless(@ARGV);
if($ARGV[0] eq "-s")
{
$spaced=1;
shift;
}
opendir(DIR, "$ARGV[0]") || die "$0: Can't open directory $ARGV[0]\n";
while($_ = readdir(DIR))
{
next unless($_ =~ m%\.txt$% && $_ !~ m%^_%);
push(@files, $_);
}
closedir(DIR);
exit if($#files == -1);
foreach $file(@files)
{
open(INPUT, "<$ARGV[0]/$file") || die "$0: Can't open $_: $!\n";
$keys{"z-filename"}=1;
while(<INPUT>)
{
$/="\n\n";
my $trash = <INPUT>;
$trash = <INPUT>;
$/="\n";
while($_ = <INPUT>)
{
chomp;
if(/:/)
{
my($key, $value) = split(/:/, $_, 2);
$value =~ s%\s+% %g;
$value =~ s%^\s+%%;
$value =~ s%\s+$%%;
my @elements = split(/\s/, $value);
if($spaced && $#elements > 0)
{
my $origkey = $key;
for(0 .. $#elements)
{
$key = $origkey . ($_+1);
$rows{$row}{$key} = $elements[$_];
$keys{$key} = 1;
}
}
else
{
$rows{$row}{$key} = $value;
$keys{$key} = 1;
}
}
$rows{$row}{"z-filename"} = $file;
}
}
close(INPUT);
$row++;
}
print join("\t", sort(keys(%keys)));
print "\n";
$row--;
my $colcount;
for(0..$row)
{
$colcount = 1;
if (defined $rows{$_})
{
my %current = %{$rows{$_}};
foreach my $column (sort(keys(%keys)))
{
if(defined($current{$column}))
{
print $current{$column};
}
else
{
print "-";
}
print "\t" unless(scalar(keys(%keys)) == $colcount);
$colcount++;
}
print "\n";
}
}

View File

@@ -0,0 +1,96 @@
# Call with the following args:
# [-s <groupSize>] filename1 [filename 2 [...]]
# Where:
# <groupSize> defines the size of the square within which nearby entries will be considered to be at the same location.
use strict;
my $debug = 0;
my $groupSize = 100.0;
my %crashCountByLocation;
sub sign
{
my $value = shift;
if ($value >= 0)
{
return 1;
}
else
{
return -1;
}
}
sub quantizeCoordinate
{
my $coordinate = shift;
return int(abs($coordinate)/$groupSize) * $groupSize * sign($coordinate);
}
sub addCrashLocation
{
my $terrainName = shift;
my $x = quantizeCoordinate(shift);
my $y = shift;
my $z = quantizeCoordinate(shift);
my $key = $terrainName . ':' . $x . ':' . $z;
++$crashCountByLocation{$key};
}
sub printCrashSummary
{
printf("count\t%25s: %6s %6s\n\n", 'terrain file', 'x', 'z');
# Sort entries by count, starting with highest.
foreach my $key (sort { $crashCountByLocation{$b} <=> $crashCountByLocation{$a} } keys %crashCountByLocation)
{
my $count = $crashCountByLocation{$key};
my @keyData = split(/:/, $key);
my $terrain = $keyData[0];
my $x = $keyData[1];
my $z = $keyData[2];
printf("%d\t%25s: %6d %6d\n", $count, $terrain, $x, $z);
}
}
# Handle options.
if (defined($ARGV[0]) && ($ARGV[0] eq '-s'))
{
shift;
$groupSize = shift;
}
print "group size: $groupSize\n" if $debug;
# Process Files
my $terrain;
my $x;
my $y;
my $z;
while (<>)
{
chomp();
# Check for terrain
if (s/^Terrain:\s*//)
{
$terrain = $_;
}
elsif (m/^Player:\s*(\S+)\s+(\S+)\s+(\S+)/)
{
$x = $1;
$y = $2;
$z = $3;
# This line depends on the Player entry coming after the Terrain entry in a .txt file.
addCrashLocation($terrain, $x, $y, $z);
}
}
printCrashSummary;

View File

@@ -0,0 +1,182 @@
###################################################
#
# createClientOTs.pl
# authored by Eric Sebesta (esebesta@soe.sony.com
#
# Purpose: When run in a directory, it generates, and submits to
# perforce a basic set of object templates (client and server
# based on the files in the directory, which must be appearances.
# The user must pass in client and server tdf files so that we can
# generate object templates appropriate for the given appearances.
#
###################################################
use Cwd;
#initialize an array with all the possible extensions a valid appearance would have
#we use this array to check that a given file is actually an appearance
@appearanceExtensions = (".lod", ".cmp", ".msh", ".sat");
#the template compiler must be run from the area where the tpf files should live, so make
#sure they are in a currently accepted location for them
$requiredSourceDir = "plt.shared\loc.shared\compiled\game\object";
$requiredSourceDirFront = "plt.shared/loc.shared/compiled/game/object";
#users must pass in 2 parameters, the appearance directory and the tdf file used to generate the tpfs
if (scalar(@ARGV) != 2)
{
die "usage: createClientOTs <appearance directory> <TDF> \nRequire 2 parameters, received $numArgs\n";
}
#if(!cwd() =~ "sys.client")
#{
# die "must be in client template directory!\n";
#}
#TODO this isn't working?
#check the current directory against the required ones
if(!cwd() =~ $requiredSourceDir)
{
if(!cwd() =~ $requiredSourceDirFront)
{
print "not in correct dir, must be in dsrc\"\\<blah blah blah>\\game\\object\" or below\n";
die;
}
}
#get the various command line parameters
my $appearanceDir = $ARGV[0];
print "appearance directory is $appearanceDir\n";
$TDF = $ARGV[1];
print "Tdf is $TDF\n";
#we're all done with initial listing, delimite with a line
print "\n";
#make sure the appearance directory exists before proceeding, since we'll want to open all those files
-e $appearanceDir or die "ERROR: appearance directory does not compute, I mean exist\n";
#read the files from the current directory
opendir CURRENTDIR, $appearanceDir or die "ERROR: can't read current directory, bad: $1";
my @files = readdir CURRENTDIR;
closedir CURRENTDIR;
#process each file, building, editing, compiling, and submitting the tpf and iff file
foreach $file (@files)
{
print "processing $file...\n";
#validate that the current file is an appearance
my $found = 0;
foreach $ext (@appearanceExtensions)
{
if($file =~ /$ext/)
{
$found = 1;
}
}
if($found == 0)
{
print " WARNING: not an appearance file, skipping\n"
}
#okay, the file exists and is an appearance, and we are in a directory to drop tpf's into, go for it
createOT($file);
#one line seperator between files
print "\n";
}
############################################################################
sub createOT #11/08/01 10:58:AM
############################################################################
{
#the new client template name is passed in as a parameter
my $appearanceFileName = @_[0];
#turn the filename into a short client template name (i.e. remove any pathing info and remove the extension)
$appearanceFileName =~ m/^(.*)\./;
my $base = $1;
my @args = ("templateCompiler", "-generate", $TDF, $base);
print "@args...";
if(system(@args) != 0)
{
print "\ncouldn't run templatecompiler for template, skipping)";
return;
}
else
{
print "success\n";
}
#now get the actual tpf filename
my $templateFileName = $base . ".tpf";
#the base template has been generated, now fill in the appearance name
my $TEMPLATE = $templateFileName;
if (-e $TEMPLATE)
{
#build the new line we want to write (the new appearance name)
my $newLine = "appearanceFilename = \"appearance\\" . $appearanceFileName . "\"\n";
#open the new tpf file for read, so we can set the appearance name
open (TEMPLATE, '<' . $templateFileName) or die "failed to open original tpf file for editing\n";
#open a temporary file for us to write the new contents into
my $tempPathname = $templateFileName . '.tmp';
open (TEMP, '>' . $tempPathname) or die "failed to open dest filename for writing [$destPathname]\n";
#search the tpf the appearance line
while ($line = <TEMPLATE>)
{
if($line =~ "appearanceFilename = ")
{
#output our new line with the appearance name
print TEMP $newLine;
}
else
{
#otherwise, write back out the original contents
print TEMP $line;
}
}
#close all filehandles
close TEMPLATE;
close TEMP;
# rename dest filename to source filename, clobbering the original source
rename $tempPathname, $templateFileName;
}
else
{
print "\ncouldn't client template file does not exist, skipping....\n";
return;
}
@args = ("templateCompiler", "-compile", $templateFileName);
print "@args...";
if(system(@args) != 0)
{
print "\ncouldn't run templatecompiler -compile for template, skipping)";
return;
}
else
{
print "success\n";
}
@args = ("templateCompiler", "-submit", $templateFileName);
print "@args...";
print "not run\n";
#if(system(@args) != 0)
#{
# print "couldn't run templatecompiler -submit for client template, skipping)";
# return;
#}
#else
#{
# print "success\n";
#}
} ##createOT

View File

@@ -0,0 +1,166 @@
###################################################
#
# createServerOTs.pl
# authored by Eric Sebesta (esebesta@soe.sony.com
#
# Purpose: When run in a directory, it generates, and submits to
# perforce a basic set of object templatesbased on the files in the
# directory, which must be appearances.
# The user must pass in client and server tdf files so that we can
# generate object templates appropriate for the given appearances.
#
###################################################
use Cwd;
#initialize an array with all the possible extensions a valid appearance would have
#we use this array to check that a given file is actually an appearance
#@appearanceExtensions = (".lod", ".cmp", ".msh", ".sat");
#the template compiler must be run from the area where the tpf files should live, so make
#sure they are in a currently accepted location for them
$requiredSourceDir = "plt.shared\loc.shared\compiled\game\object";
$requiredSourceDirFront = "plt.shared/loc.shared/compiled/game/object";
#users must pass in 3 parameters, the appearance directory and the tdf file used to generate the tpfs
if (scalar(@ARGV) != 3)
{
die "usage: createServerOTs <clientTemplateRelative dir, i.e. \"tangible\"> <appearance dir> <TDF> \nRequire 2 parameters, received $numArgs\n";
}
#if(!cwd() =~ "sys.server")
#{
# die "must be in server template directory!\n";
#}
#TODO this isn't working?
#check the current directory against the required ones
if(!cwd() =~ $requiredSourceDir)
{
if(!cwd() =~ $requiredSourceDirFront)
{
print "not in correct dir, must be in dsrc\"\\<blah blah blah>\\game\\object\" or below\n";
die;
}
}
#get the various command line parameters
my $clientTemplateRelativeDir = $ARGV[0];
print "client relative directory is $clientTemplateRelativeDir\n";
my $appearanceDir = $ARGV[1];
print "appearance directory is $appearanceDir\n";
$TDF = $ARGV[2];
print "Tdf is $TDF\n";
#we're all done with initial listing, delimite with a line
print "\n";
#make sure the appearance directory exists before proceeding, since we'll want to open all those files
#-e $appearanceDir or die "ERROR: appearance directory does not compute, I mean exist\n";
#read the files from the current directory
opendir CURRENTDIR, $appearanceDir or die "ERROR: can't read current directory, bad: $1";
my @files = readdir CURRENTDIR;
closedir CURRENTDIR;
#process each file, building, editing, compiling, and submitting the tpf and iff file
foreach $file (@files)
{
print "processing $file...\n";
createOT($file);
#one line seperator between files
print "\n";
}
############################################################################
sub createOT #11/08/01 10:58:AM
############################################################################
{
#the new server template name is passed in as a parameter
my $fileName = @_[0];
#turn the filename into a short server template name (i.e. remove any pathing info and remove the extension)
$fileName =~ m/^(.*)\./;
my $base = $1;
my @args = ("templateCompiler", "-generate", $TDF, $base);
print "@args...";
if(system(@args) != 0)
{
print "\ncouldn't run templatecompiler for template, skipping)";
return;
}
else
{
print "success\n";
}
#now get the actual iff filename
my $templateSourceFileName = $base . ".tpf";
my $compiledClientFileName = $base . ".iff";
#the base template has been generated, now fill in the client template name
my $TEMPLATE = $templateSourceFileName;
if (-e $TEMPLATE)
{
#build the new line we want to write (the new appearance name
$newLine = "clientTemplate = \"" . $clientTemplateRelativeDir . "\\" . $compiledClientFileName . "\"\n";
#open the new tpf file for read, so we can set the appearance name
open (TEMPLATE, '<' . $templateSourceFileName) or die "failed to open original tpf file for editing\n";
#open a temporary file for us to write the new contents into
my $tempPathname = $templateSourceFileName . '.tmp';
open (TEMP, '>' . $tempPathname) or die "failed to open dest filename for writing [$destPathname]\n";
#search the tpf the appearance line
while ($line = <TEMPLATE>)
{
if($line =~ "clientTemplate =")
{
#output our new line with the client template name
print TEMP $newLine;
}
else
{
#otherwise, write back out the original contents
print TEMP $line;
}
}
#close all filehandles
close TEMPLATE;
close TEMP;
# rename dest filename to source filename, clobbering the original source
rename $tempPathname, $templateSourceFileName;
}
@args = ("templateCompiler", "-compile", $templateSourceFileName);
print "@args...";
if(system(@args) != 0)
{
print "\ncouldn't run templatecompiler -compile for template, skipping)";
return;
}
else
{
print "success\n";
}
@args = ("templateCompiler", "-submit", $templateSourceFileName);
print "@args...";
print "not run\n";
#if(system(@args) != 0)
#{
# print "couldn't run templatecompiler -submit for client template, skipping)";
# return;
#}
#else
#{
# print "success\n";
#}
} ##createOT

View File

@@ -0,0 +1,367 @@
# ======================================================================
#
# Customization Variable Tool
# Copyright 2003, Sony Online Entertainment, Inc.
#
# ======================================================================
use strict;
use File::Find;
use POSIX qw(strftime);
# ======================================================================
# Constants
my $maxAllowableVariableId = 127;
my $dataFormatVersionNumber = 1;
my $firstAssignableId = 1;
# Names of customization variables.
my %countsByVariableName;
# Name to id assignment.
my %idsByVariableName;
my $newVariableCount = 0;
# Action options.
my $doPrintReport = 0;
my $doGenerateMifMapFile = 0;
# Report printing options.
my $printTpfFileNames = 0;
my $printSortByCount = 0;
my $printSortByName = 0;
my $reverseSort = 0;
# Id map file generation options.
my $mifFileName = "";
my $mifFileMustExist = 1;
my $debug = 0;
# ======================================================================
# SUBROUTINES
# ======================================================================
# ======================================================================
sub processArgs
{
# Process args. Args must come first.
while (defined($ARGV[0]) && ($ARGV[0] =~ m/^-([a-zA-Z]*)$/))
{
if ($1 eq "i")
{
$doPrintReport = 1;
}
elsif ($1 eq "g")
{
$doGenerateMifMapFile = 1;
}
elsif ($1 eq "F")
{
# Support first-time mif file generation, but force it to be a flag
# so the default is to die if not explicity specified and the mif
# file doesn't exist.
$mifFileMustExist = 0;
}
elsif ($1 eq "o")
{
die "-o option requires a filename to be specified after it (e.g. -o customization_id_manager.mif)\n" if !defined($ARGV[1]);
$mifFileName = $ARGV[1];
shift @ARGV;
die "filename [$mifFileName] should end in extension \".mif\"\n" if !($mifFileName =~ m/\.mif$/);
}
elsif ($1 eq "t")
{
$printTpfFileNames = 1;
}
elsif ($1 eq "c")
{
$printSortByCount = 1;
}
elsif ($1 eq "n")
{
$printSortByName = 1;
}
elsif ($1 eq "r")
{
$reverseSort = 1;
}
elsif ($1 eq "d")
{
$debug = 1;
}
shift @ARGV;
}
#-- Ensure we do at least some activity. Assume report generation is default.
if (($doPrintReport == 0) && ($doGenerateMifMapFile == 0))
{
$doPrintReport = 1;
}
#-- Ensure we'll print at least some output. Default is print-by-count if no printing option is specified.
if (($printSortByCount == 0) && ($printSortByName == 0))
{
$printSortByCount = 1;
}
}
# ======================================================================
sub findFileHandler
{
#-- Check if this is a TPF file.
if (m/^.*\.tpf$/)
{
#-- Indicate file we're testing.
print "Processing [$File::Find::name].\n" if $printTpfFileNames;
#-- Open the TPF file.
open(FILE, $_);
#-- Scan all variable names within the TPF file.
while (<FILE>)
{
chomp();
if (m/variableName="([^"]*)\"/) # last double-quote escaped for Emacs font-lock mode.
{
$countsByVariableName{$1}++;
}
}
#-- Close the file.
close(FILE);
}
}
# ======================================================================
sub collectCustomizationVariableData
{
# Setup directories to check.
@ARGV = ('.') if !defined($ARGV[0]);
# Do the find to scan in all TPF filenames.
find (\&findFileHandler, @ARGV);
}
# ======================================================================
sub printReport
{
# Handle printing sorted by name.
if ($printSortByName)
{
my @sortedKeys = sort keys(%countsByVariableName);
@sortedKeys = reverse @sortedKeys if $reverseSort;
print "Variable names sorted by name (" . @sortedKeys . " unique variable names):\n";
print "variable name\tcount\n";
foreach my $variableName (@sortedKeys)
{
my $count = $countsByVariableName{$variableName};
print "$variableName\t$count\n";
}
print "\n";
}
if ($printSortByCount)
{
my @sortedKeys = sort {$countsByVariableName{$b} <=> $countsByVariableName{$a}} keys(%countsByVariableName);
@sortedKeys = reverse @sortedKeys if $reverseSort;
print "Variable names sorted by name (" . @sortedKeys . " unique variable names):\n";
print "count\tvariable name\n";
foreach my $variableName (@sortedKeys)
{
my $count = $countsByVariableName{$variableName};
print "$count\t$variableName\n";
}
print "\n";
}
}
# ======================================================================
sub collectExistingVariableNameAssignments
{
open(MIF_FILE, $mifFileName) or die "failed to open specified mif file [$mifFileName]: $!";
my $nextAssignmentId = $firstAssignableId;
my $expectingId = 1;
while (<MIF_FILE>)
{
chomp();
if (m/int16\s+(\d+)\s*$/)
{
# Ensure we're expecting a new id.
die "error: file [$mifFileName] appears malformed, out of order int16/cstring declarations.\n" if !$expectingId;
$expectingId = 0;
$nextAssignmentId = $1;
}
elsif (m/cstring\s+\"([^\"]+)\"\s*$/)
{
# Ensure we're expecting a variable name.
die "error: file [$mifFileName] appears malformed, out of order int16/cstring declarations.\n" if $expectingId;
$expectingId = 1;
# Add new variable name. It is associated with $nextAssignmentId collected previously.
$idsByVariableName{$1} = $nextAssignmentId;
print "<existing: mapping variable name [$1] to [$nextAssignmentId]>\n" if $debug;
}
}
close(MIF_FILE);
}
# ======================================================================
sub writeMifFile
{
open(MIF_FILE, ">$mifFileName") or die "failed to open mif file [$mifFileName] for writing: $!";
my $timeString = strftime "%a %b %e %H:%M:%S %Y", localtime(time());
print MIF_FILE "// ======================================================================\n";
print MIF_FILE "// Output generated by Perl script \"$0\"\n";
print MIF_FILE "// Generation time: $timeString\n";
print MIF_FILE "//\n";
print MIF_FILE "// Do not hand-edit this file! It is generated by the build process.\n";
print MIF_FILE "// Changing values from a previous run without a database update will\n";
print MIF_FILE "// invalidate database-stored customization data.\n";
print MIF_FILE "// ======================================================================\n\n";
print MIF_FILE "form \"CIDM\"\n";
print MIF_FILE "{\n";
print MIF_FILE "\tform \"0001\"\n";
print MIF_FILE "\t{\n";
print MIF_FILE "\t\tchunk \"DATA\"\n";
print MIF_FILE "\t\t{\n";
foreach my $variableName (sort { $idsByVariableName{$a} <=> $idsByVariableName{$b} } keys %idsByVariableName)
{
print MIF_FILE "\t\t\tint16\t$idsByVariableName{$variableName}\n";
print MIF_FILE "\t\t\tcstring\t\"$variableName\"\n\n";
}
print MIF_FILE "\t\t}\n";
print MIF_FILE "\t}\n";
print MIF_FILE "}\n";
close(MIF_FILE);
print "<success: wrote new customization id manager data file [$mifFileName]>\n" if $debug;
}
# ======================================================================
sub assignNewVariableIds
{
# Setup starting id: should be the same as # entries in assignment map.
my @sortedValues = sort {$b <=> $a} values %idsByVariableName;
my $nextAssignmentId = $firstAssignableId;
$nextAssignmentId = ($sortedValues[0] + 1) if defined($sortedValues[0]);
print "<firstNewId: $nextAssignmentId>\n" if $debug;
# Process new IDs sorted by frequency from most to least, causing
# lower ID values to be assigned to higher-frequency items. This
# could be useful if some of the lower frequency items are really
# typos and need to be shuffled around.
foreach my $variableName (sort {$countsByVariableName{$b} <=> $countsByVariableName{$a}} keys %countsByVariableName)
{
# Check if variable is assigned yet.
if (!defined($idsByVariableName{$variableName}))
{
$idsByVariableName{$variableName} = $nextAssignmentId;
print "<new: mapping variable name [$variableName] to [$nextAssignmentId]>\n" if $debug;
++$nextAssignmentId;
++$newVariableCount;
}
}
}
# ======================================================================
sub generateMifMapFile
{
# Collect existing mif map assignments.
if (-f $mifFileName)
{
collectExistingVariableNameAssignments();
}
elsif ($mifFileMustExist)
{
if (length($mifFileName) < 1)
{
die "error: must specify filename for existing and output mif file with the -o flag.\n";
}
else
{
die "error: Customization id manager file must exist to preserve existing mappings.\nerror: Failed to find [$mifFileName].\nerror: Use -F for first-time file generation, don't do this unless you know what you're doing!\n";
}
}
# Generate assignments for non-populated but existing customization variables.
assignNewVariableIds();
# Check if we've exceeded the max assignable id value.
my @sortedAssignedIds = sort {$a <=> $b} values %idsByVariableName;
my $idCount = @sortedAssignedIds;
if ($idCount > 0)
{
my $maxAssignedId = $sortedAssignedIds[$idCount - 1];
print "<maxAssignedId: $maxAssignedId>\n" if $debug;
if ($maxAssignedId > $maxAllowableVariableId)
{
die "error: new unassigned customization variable ids needed but no more room.\nerror: Either unused names must be removed with database remapping or a new data format must be implemented.\nNeed id of $maxAssignedId but max allowable is $maxAllowableVariableId for format version $dataFormatVersionNumber.\n";
}
}
# Write new mif file if any changes.
if ($newVariableCount > 0)
{
writeMifFile();
}
else
{
print "skipping file generation: no new customization variable names found.\n";
}
}
# ======================================================================
# PROGRAM STARTING POINT.
# ======================================================================
# Program starts here.
{
# Handle arguments.
processArgs();
# Collect customization variable data.
collectCustomizationVariableData();
# Handle report generation.
if ($doPrintReport)
{
printReport();
}
# Handle mif file generation.
if ($doGenerateMifMapFile)
{
generateMifMapFile();
}
}
# ======================================================================

View File

@@ -0,0 +1,437 @@
# ======================================================================
#
# custUpgrade.pl
# Copyright 2003 Sony Online Entertainment, Inc.
# All Rights Reserved.
#
# ======================================================================
# Used to upgrade SWG customization data from an older database format
# to a newer database format. Note the exact upgrade logic needed will
# be different in any upgrade situation, but this should be a good template
# for most of the code in the event of another customization data upgrade
# some time in the future.
# Perl modules DBI and DBD::Oracle must be installed to run this tool. See www.perl.com for info on getting these modules.
# You must have PERL5LIB (or PERLLIB) set to your mapping for //depot/swg/current/tools/perllib.
use Customization;
use DBI;
use strict;
# ======================================================================
# Module Globals
# ======================================================================
#options
my $userName = "";
my $password = "changeme";
my $databaseName = "swodb";
my $debug = 0;
my $noChanges = 0;
my $doUpgrade = 0;
my $commitCount = 0;
my $limitRowCount = 0;
my $progressStep = 0;
my $defaultFilename = '../dsrc/sku.0/sys.shared/compiled/game/customization/customization_id_manager.mif';
my $customizationIdManagerFilename = $defaultFilename;
# ======================================================================
sub printHelp
{
print "Calling syntax:\n";
print "\tperl -w custUpgrade.pl -u <database username> [-p <database password>] [-D <database>] [-d] [-n] [-U] [-c <commit count>] [-l <limit row count>] [-m <pathToCustomizationIdManagerMifFile>] [-s <progressOutputStep>]\n";
print "Option description:\n";
print "\t-u: specifies the name of the user for the Oracle database.\n";
print "\t-p: [optional] specifies the password for the user of the Oracle database. Default: changeme.\n";
print "\t-D: [optional] specifies the database to attach to. Default: swodb.\n";
print "\t-d: [optional] turn on extensive debug-level output.\n";
print "\t-n: [optional] do not make changes to the database, just print what would have happened.\n";
print "\t-U: [optional] Upgrade customization data in the database.\n";
print "\t-c: [optional] commit every 'commit count' number of rows processed, or 0 for single commit at the end. Default: 0.\n";
print "\t-l: [optional] limit database processing to first <limit row count> rows or 0 for no limit. Default: 0.\n";
print "\t-m: [optional] specify path to CustomizationIdManager's mif version of initialization file. Default: $defaultFilename\n";
print "\t-s: [optional] print a progress line every progressStep percent or 0 if no output. Default: 0.\n";
print "\t-h: [optional] print this help info.\n";
}
# ======================================================================
sub collectOptions
{
my $showHelp = 0;
my $exitCode = 0;
while (defined($ARGV[0]) && ($ARGV[0] =~ m/^-(.*)$/))
{
if ($1 eq 'u')
{
# Grab username.
if (@ARGV < 2)
{
print "-u option missing <database username> specification.\n";
$exitCode = 1;
last;
}
$userName = $ARGV[1];
print "<username: $userName>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'p')
{
# Grab password.
if (@ARGV < 2)
{
print "-p option missing <password> specification.\n";
$exitCode = 1;
next;
}
$password = $ARGV[1];
print "<password: $password>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'D')
{
# Grab database name.
if (@ARGV < 2)
{
print "-D option missing <database> specification.\n";
$exitCode = 1;
next;
}
$databaseName = $ARGV[1];
print "<database: $databaseName>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'd')
{
$debug = 1;
$Customization::Debug = 1;
}
elsif ($1 eq 'n')
{
$noChanges = 1;
}
elsif ($1 eq 'U')
{
$doUpgrade = 1;
}
elsif ($1 eq 'h')
{
$showHelp = 1;
}
elsif ($1 eq 'c')
{
# Grab commit count.
if (@ARGV < 2)
{
print "-c option missing <commit count> specification.\n";
$exitCode = 1;
next;
}
$commitCount = $ARGV[1];
print "<commit count: $commitCount>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'l')
{
# Grab commit count.
if (@ARGV < 2)
{
print "-l option missing <limit row count> specification.\n";
$exitCode = 1;
next;
}
$limitRowCount = $ARGV[1];
print "<limitRowCount: $limitRowCount>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'm')
{
# Grab commit count.
if (@ARGV < 2)
{
print "-m option missing <CustomizationIdManager MIF file> specification.\n";
$exitCode = 1;
next;
}
$customizationIdManagerFilename = $ARGV[1];
print "<customizationIdManagerFilename: $customizationIdManagerFilename\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 's')
{
# Grab commit count.
if (@ARGV < 2)
{
print "-s option missing <progressStepPercent> specification.\n";
$exitCode = 1;
next;
}
$progressStep = $ARGV[1];
print "<progressStep: $progressStep>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
else
{
warn "unknown option [$1].";
$exitCode = 1;
}
# Process next argument.
shift @ARGV;
}
# Check for missing options.
if (length $userName < 1)
{
print "missing -u username option.\n";
$exitCode = 1;
}
# Show help as needed.
if ($showHelp || ($exitCode != 0))
{
printHelp();
exit($exitCode);
}
}
# ======================================================================
# input: old-style customization ascii string.
# output: new-style customization binary data (as string) (unescaped --- can contain embedded NULLs).
# ======================================================================
sub convertOldToNew
{
# Get the string.
my $oldString = shift;
# fill directory contents from old string.
my %variableInfo;
my $rc = getVariableInfoFromOldString(%variableInfo, $oldString);
if (!$rc)
{
warn "convertOldToNew:failed to get variable info from old-style customization data string [$oldString]\n";
return "";
}
return createNewDataFromVariableInfo(%variableInfo);
}
# ======================================================================
sub doUpgrade
{
my $returnCode;
# Open the database connection.
my $dbHandle = DBI->connect("dbi:Oracle:$databaseName", $userName, $password, { RaiseError => 1, AutoCommit => 0 });
error("failed to open database: [$DBI::errstr]") if !defined($dbHandle);
print "<connection: opened connection to database [$databaseName] as user [$userName] successfully.>\n" if $debug;
# Find # rows that match our criteria of non-zero-length customization data.
my $totalRowCount = 0;
{
my $statementHandle = $dbHandle->prepare("SELECT COUNT(*) FROM tangible_objects WHERE LENGTH(appearance_data) > 0") or die $dbHandle->errstr;
$statementHandle->execute() or die $statementHandle->errstr;
my @row = $statementHandle->fetchrow_array;
die($statementHandle->errString) if !@row;
$totalRowCount = $row[0];
print "<totalRowCount: $totalRowCount>\n" if $debug;
}
# Progress bar uses limitRowCount or totalRowCount depending on whether row limiting is in effect.
my $progressTotalRowCount = $totalRowCount;
if (($limitRowCount > 0) && ($limitRowCount < $totalRowCount))
{
$progressTotalRowCount = $limitRowCount;
}
# Process rows.
my $uncommittedRowCount = 0;
my $totalCommittedRowCount = 0;
my $processedRowCount = 0;
my $failedRowCount = 0;
my $sumOldStringSize = 0;
my $sumNewDataSize = 0;
my $sumNewStringSize = 0;
my $lastPrintedPercent = 0;
{
# Prepare the SELECT statement.
my $statementHandle = $dbHandle->prepare("SELECT object_id, appearance_data FROM tangible_objects WHERE LENGTH(appearance_data) > 0") or die $dbHandle->errstr;
$statementHandle->execute() or die $statementHandle->errstr;
# Prepare the UPDATE statement.
my $updateStatementHandle = $dbHandle->prepare("UPDATE tangible_objects SET appearance_data = ? WHERE object_id = ?") or die $dbHandle->errstr;
while (my @row = $statementHandle->fetchrow_array)
{
# Validate row entry count.
die "Returned row has " . @row . "entries, expecting 2." if (@row != 2);
++$processedRowCount;
# Retrieve object id and old customization data.
my $objectId = $row[0];
my $oldCustomizationString = $row[1];
print "<row: num=[$processedRowCount] id=[$objectId]: string=[$oldCustomizationString]>\n" if $debug;
# Keep track of old customization string size.
$sumOldStringSize += length $oldCustomizationString;
# Convert the row.
my $newCustomizationData = convertOldToNew($oldCustomizationString);
my $newDataLength = length $newCustomizationData;
if (!defined($newCustomizationData) || ($newDataLength < 1))
{
++$failedRowCount;
print STDERR "failed to convert old customization data [$oldCustomizationString] (total failed rows=$failedRowCount).\n";
}
else
{
# Track new unescaped binary data length.
$sumNewDataSize += $newDataLength;
# Convert binary data to escaped string form.
my $newCustomizationString = escapeBinaryData($newCustomizationData);
# Track new escaped string data length.
my $newStringLength = length $newCustomizationString;
if (!defined($newCustomizationString) || ($newStringLength < 1))
{
++$failedRowCount;
print STDERR "failed to convert new binary customization data [$newCustomizationData] to string (total failed rows=$failedRowCount).\n";
}
else
{
$sumNewStringSize += length $newCustomizationString;
# Update the database with new entry.
if (!$noChanges)
{
# Execute the update.
$updateStatementHandle->execute($newCustomizationString, $objectId) or die $statementHandle->errstr;
# Check if we should commit.
++$uncommittedRowCount;
if (($commitCount != 0) && ($uncommittedRowCount >= $commitCount))
{
# Commit now.
my $returnCode = $dbHandle->commit or die $dbHandle->errstr;
$totalCommittedRowCount += $uncommittedRowCount;
print "<commit: $uncommittedRowCount rows committed now, $processedRowCount total, returnCode=$returnCode.>\n" if $debug;
$uncommittedRowCount = 0;
}
}
else
{
print "<update: would do UPDATE tangible_objects SET appearance_data = (" . $newStringLength . " byte string) WHERE object_id = [$objectId]>\n" if $debug;
}
}
}
# Handle progress monitoring.
if ($progressStep > 0)
{
my $progressPercent = 100.0 * $processedRowCount / $progressTotalRowCount;
if ($progressPercent >= ($lastPrintedPercent + $progressStep))
{
$lastPrintedPercent = $progressPercent;
printf("progress: %d%% complete.\n", $lastPrintedPercent);
}
}
# Handle row limiting.
if (($limitRowCount > 0) && ($processedRowCount >= $limitRowCount))
{
print "<limitRowCount: specified row count limit [$limitRowCount] hit, finishing now.>\n" if $debug;
last;
}
}
}
# Do final commit.
if (!$noChanges)
{
my $returnCode = $dbHandle->commit or die $dbHandle->errstr;
$totalCommittedRowCount += $uncommittedRowCount;
print "<commit: $uncommittedRowCount rows committed now, $processedRowCount total, returnCode=$returnCode.>\n" if $debug;
$uncommittedRowCount = 0;
}
# Close the database connection.
$returnCode = $dbHandle->disconnect or warn $dbHandle->errstr;
print "<disconnect: return code $returnCode>" if $debug;
# Print statistics
print "Completed upgrade process, printing statistics.\n";
print "\tTotal rows processed: $processedRowCount\n";
print "\tTotal rows changed: $totalCommittedRowCount\n\n";
my $oldAverage = 1;
$oldAverage = ($sumOldStringSize / $processedRowCount) if $processedRowCount > 0;
printf("\tTotal old customization string data: $sumOldStringSize bytes (average: %.2f bytes each)\n", $oldAverage) if $processedRowCount > 0;
my $newStringCount = $processedRowCount - $failedRowCount;
my $newAverage = 1;
$newAverage = ($sumNewStringSize / $newStringCount) if $newStringCount > 0;
printf("\tTotal new customization string data: $sumNewStringSize bytes (average: %.2f bytes each)\n", $newAverage) if $newStringCount > 0;
my $compressionFraction = $newAverage / $oldAverage;
printf "\tCompressed to %.2f%% of original size.\n", $compressionFraction * 100;
my $difference = $sumNewStringSize - $sumNewDataSize;
printf("\tTotal overhead for binary data escaping: $difference bytes (%.2f%% increase).\n", 100.0 * (($sumNewStringSize / $sumNewDataSize) - 1.0)) if $sumNewDataSize > 0;
}
# ======================================================================
# Program Starts Here
# ======================================================================
{
collectOptions();
if ($doUpgrade)
{
initializeCustomization($customizationIdManagerFilename);
doUpgrade();
}
}
# ======================================================================

View File

@@ -0,0 +1,476 @@
# ======================================================================
#
# custView.pl
# Copyright 2003 Sony Online Entertainment, Inc.
# All Rights Reserved.
#
# ======================================================================
# Used to output customization data assignments for objects in a
# SWG database. Can view customization values for a list of object
# ids or for all object ids in the database.
# Perl modules DBI and DBD::Oracle must be installed to run this tool. See www.perl.com for info on getting these modules.
# You must have PERL5LIB (or PERLLIB) set to your mapping for //depot/swg/current/tools/perllib.
use strict;
use Customization;
use DBI;
# ======================================================================
# Globals
# ======================================================================
my $modeIsView = 0;
my $modeIsChange = 0;
my $userName = "";
my $password = "changeme";
my $databaseName = "swodb";
my $debug = 0;
my $showAll = 0;
my $useOldFormat = 0;
my $useFormatVersion = 1;
my $defaultFilename = '../dsrc/sku.0/sys.shared/compiled/game/customization/customization_id_manager.mif';
my $customizationIdManagerFilename = $defaultFilename;
my $dbHandle;
my $dumpFileName;
my $dumpFileEntryNumber = 1;
# ======================================================================
sub printHelp
{
print "Calling syntax:\n";
print "\n";
print "show help:\n";
print "\t$0 -h\n";
print "\n";
print "view human-readable customization from database:\n";
print "\t$0 -V -u <database username> [-p <database password>] [-D <database>] [-d]\n";
print "\t [-m <pathToCustomizationIdManagerMifFile>] [-f format]\n";
print "\t [-a | [objectId [objectId...]]]\n";
print "\n";
print "change customization data in the database:\n";
print "\t$0 -C -u <database username> [-p <database password>] [-D <database>] [-d]\n";
print "\t -1 <path to 1-line format dump file> [-e <entry number within dump file>] objectId\n";
print "\n";
print "Option description:\n";
print "\t-V: major operating mode: view database info.\n";
print "\t-C: major operating mode: change database entry.\n";
print "\t-u: specifies the name of the user for the Oracle database.\n";
print "\t-p: [optional] specifies the password for the user of the Oracle database. Default: changeme.\n";
print "\t-D: [optional] specifies the database to attach to. Default: swodb.\n";
print "\t-d: [optional] turn on extensive debug-level output.\n";
print "\t-m: [optional] specify path to CustomizationIdManager's mif version of initialization file.\n";
print "\t Default: $defaultFilename\n";
print "\t-a: [optional] list customization variables for all objects in the database that have any customization info.\n";
print "\t-f: [optional] customization string format: format = 1 (for new packed format version 1), old2 (for old unpacked format version 2).\n";
print "\t Default: 1.\n";
print "\t-h: [optional] print this help info.\n";
print "\t-1: filename containing 1-line dump format (one entry per line) of Oracle select dump(appearance_data) data.\n";
print "\t-e: [optional] specifies the 1-based entry count to use if the dump file has multiple lines. Default: 1.\n";
}
# ======================================================================
sub collectOptions
{
my $showHelp = 0;
my $exitCode = 0;
while (defined($ARGV[0]) && ($ARGV[0] =~ m/^-(.*)$/))
{
if ($1 eq 'u')
{
# Grab username.
if (@ARGV < 2)
{
print "-u option missing <database username> specification.\n";
$exitCode = 1;
last;
}
$userName = $ARGV[1];
print "<username: $userName>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'p')
{
# Grab password.
if (@ARGV < 2)
{
print "-p option missing <password> specification.\n";
$exitCode = 1;
next;
}
$password = $ARGV[1];
print "<password: $password>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'D')
{
# Grab database name.
if (@ARGV < 2)
{
print "-D option missing <database> specification.\n";
$exitCode = 1;
next;
}
$databaseName = $ARGV[1];
print "<database: $databaseName>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'C')
{
$modeIsChange = 1;
print "major mode is change\n" if $debug;
}
elsif ($1 eq 'd')
{
$debug = 1;
$Customization::Debug = 1;
}
elsif ($1 eq 'a')
{
$showAll = 1;
}
elsif ($1 eq 'h')
{
$showHelp = 1;
}
elsif ($1 eq 'm')
{
# Grab commit count.
if (@ARGV < 2)
{
print "-m option missing <CustomizationIdManager MIF file> specification.\n";
$exitCode = 1;
next;
}
$customizationIdManagerFilename = $ARGV[1];
print "<customizationIdManagerFilename: $customizationIdManagerFilename\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'f')
{
# Grab commit count.
if (@ARGV < 2)
{
print "-f option missing <format> specification.\n";
$exitCode = 1;
next;
}
if ($ARGV[1] =~ s/^old//i)
{
$useOldFormat = 1;
}
print "<useOldFormat: $useOldFormat>\n" if $debug;
$useFormatVersion = $ARGV[1];
print "<useFormatVersion: $useFormatVersion>\n" if $debug;
# Skip past arg.
shift @ARGV;
}
elsif ($1 eq 'V')
{
$modeIsView = 1;
print "major mode is viewing\n" if $debug;
}
elsif ($1 eq '1')
{
$dumpFileName = $ARGV[1];
shift @ARGV;
print "dumpFileName=[$dumpFileName]\n" if $debug;
}
elsif ($1 eq 'e')
{
$dumpFileEntryNumber = $ARGV[1];
shift @ARGV;
print "dumpFileEntryNumber=$dumpFileEntryNumber\n" if $debug;
}
else
{
warn "unknown option [$1].";
$exitCode = 1;
}
# Process next argument.
shift @ARGV;
}
# Check for missing options.
if (!$showHelp && (length $userName < 1))
{
print "missing -u username option.\n";
$exitCode = 1;
}
# Make sure show all or command line args exist.
if (!$showHelp && (!$showAll && (@ARGV < 1)))
{
print "must specify one or more object IDs or -a option for all objects.\n";
$exitCode = 1;
}
# Show help as needed.
if ($showHelp || ($exitCode != 0))
{
printHelp();
exit($exitCode);
}
}
sub getVariableInfo(\%$)
{
my $variableInfoRef = shift;
my $customizationString = shift;
if ($useOldFormat)
{
if ($useFormatVersion == 2)
{
getVariableInfoFromOldString(%$variableInfoRef, $customizationString);
}
else
{
die "The only old version format supported is version 2, user specified [$useFormatVersion].";
}
}
else
{
if ($useFormatVersion == 1)
{
getVariableInfoFromNewString(%$variableInfoRef, $customizationString);
}
else
{
die "New version format [$useFormatVersion] unsupported.";
}
}
}
# ======================================================================
sub printView($\%)
{
my $objectId = shift;
my $variableInfoRef = shift;
print "object id: $objectId\n";
dumpVariableInfo(%$variableInfoRef);
print "\n";
}
# ======================================================================
sub handleRow(\@)
{
my $rowRef = shift;
# Validate row entry count.
die "Returned row has " . @$rowRef . "entries, expecting 2." if (@$rowRef != 2);
# Retrieve object id and old customization data.
my $objectId = $$rowRef[0];
my $customizationString = $$rowRef[1];
print "<row: id=[$objectId]: string length [" . (length $customizationString) . "]>\n" if $debug;
my %variableInfo = ();
my $success = getVariableInfo(%variableInfo, $customizationString);
die "getVariableInfo() failed for object id [$objectId]." if !$success;
printView($objectId, %variableInfo);
}
# ======================================================================
sub doView
{
if ($showAll)
{
print "<viewing: all>\n" if $debug;
# Prepare the SELECT statement: grab all non-empty appearance_data and associated object ids.
my $statementHandle = $dbHandle->prepare("SELECT object_id, appearance_data FROM tangible_objects WHERE LENGTH(appearance_data) > 0") or die $dbHandle->errstr;
$statementHandle->execute() or die $statementHandle->errstr;
while (my @row = $statementHandle->fetchrow_array)
{
handleRow(@row);
}
}
else
{
print "<viewing: [@ARGV]>\n" if $debug;
# Prepare the SELECT statement: grab all non-empty appearance_data and associated object ids.
my $statementHandle = $dbHandle->prepare("SELECT object_id, appearance_data FROM tangible_objects WHERE (LENGTH(appearance_data) > 0) AND object_id = ?") or die $dbHandle->errstr;
for (; defined($ARGV[0]); shift @ARGV)
{
$statementHandle->execute($ARGV[0]) or die $statementHandle->errstr;
my @row = $statementHandle->fetchrow_array;
if (!@row)
{
print "object id [$ARGV[0]] has no customization data.\n";
next;
}
handleRow(@row);
}
}
}
# ----------------------------------------------------------------------
sub convertOracleDumpToString
{
my $oracleDumpString = shift;
my $newString = "";
# remove header info.
$oracleDumpString =~ s/^\s*(\d+)?.*:\s*//;
my $objectId = $1;
while (length($oracleDumpString) > 0)
{
if ($oracleDumpString =~ s/^(\d+)(\s*,\s*)?//)
{
$newString .= chr($1);
}
else
{
print STDERR "convertOracleDumpToString: ", length($oracleDumpString), " characters remain: [val=", ord(substr($oracleDumpString,0,1)), "].\n";
return $newString;
}
}
return $newString;
}
# ----------------------------------------------------------------------
sub extractAppearanceDataFromFile
{
my $dumpFile;
open($dumpFile, '< ' . $dumpFileName) or die "failed to open dump file [$dumpFileName]: $!";
my $entry = 1;
while (<$dumpFile>)
{
# Check if we're dealing with the proper entry.
if ($entry == $dumpFileEntryNumber)
{
chomp;
my $appearanceData = convertOracleDumpToString($_);
close($dumpFile) or die "Failed to close dump file: $!";
return $appearanceData;
}
# Increment loop.
++$entry;
}
close($dumpFile) or die "Failed to close dump file: $!";
die "Entry [$dumpFileEntryNumber] does not exist in file [$dumpFileName] with [$entry] entries.";
}
# ----------------------------------------------------------------------
sub updateAppearanceData
{
# Retrieve args.
my $objectId = shift;
my $appearanceData = shift;
# Execute query.
my $rowCount = $dbHandle->do("UPDATE tangible_objects SET appearance_data=? WHERE object_id=$objectId", undef, $appearanceData) or die $dbHandle->errstr;
$dbHandle->commit() or die $dbHandle->errstr;
print "[$rowCount] rows updated.\n";
}
# ----------------------------------------------------------------------
sub doChange
{
# Get the line.
my $appearanceData = extractAppearanceDataFromFile();
die "Could not extract appearance data from 1-line dump file.\n" if !defined($appearanceData);
# Update the database.
die "Expecting objectId at end of line.\n" if (@ARGV != 1);
my $objectId = $ARGV[0];
updateAppearanceData($objectId, $appearanceData);
}
# ----------------------------------------------------------------------
sub connectDatabase
{
# Open the database connection.
$dbHandle = DBI->connect("dbi:Oracle:$databaseName", $userName, $password, { RaiseError => 1, AutoCommit => 0 });
error("failed to open database: [$DBI::errstr]") if !defined($dbHandle);
print "<connection: opened connection to database [$databaseName] as user [$userName] successfully.>\n" if $debug;
}
# ----------------------------------------------------------------------
sub disconnectDatabase
{
# Close the database connection.
my $returnCode = $dbHandle->disconnect or warn $dbHandle->errstr;
print "<disconnect: return code $returnCode>\n" if $debug;
}
# ======================================================================
# Program Starts Here
# ======================================================================
{
collectOptions();
connectDatabase();
if ($modeIsView)
{
Customization::initializeCustomization($customizationIdManagerFilename);
doView();
}
elsif ($modeIsChange)
{
doChange();
}
else
{
die "Major mode is neither viewing or changing.\n";
}
disconnectDatabase();
}
# ======================================================================

View File

@@ -0,0 +1,106 @@
#!/usr/bin/perl
use strict;
use warnings;
# ----------------------------------------------------------------------
# This script is used to contain all custom build steps.
# Having this logic in here allows us to make global changes
# to the custom builds with ease as well as add error checking
# in one location.
# ----------------------------------------------------------------------
my $thisScript = $0;
$thisScript =~ s%^(.*[\\\/])%%;
usage() if (!@ARGV);
# ----------------------------------------------------------------------
sub usage
{
my $message = q@
Usage:
$thisScript <command> <command arguments>
Valid commands:
moc <InputPath> <TargetDir> <InputName>
ui <InputPath> <TargetDir> <InputName> <BuildType>
@;
die "$message\n";
}
sub processMoc
{
# ..\..\..\..\..\..\external\3rd\library\qt\3.3.4\bin\moc -i $(InputPath) -o $(TargetDir)\$(InputName).moc
die "moc takes 3 arguments: <InputPath> <TargetDir> <InputName>\n" if (@_ != 3);
my $inputPath = shift;
my $targetDir = shift;
my $inputName = shift;
print "Executing moc for $inputPath, $targetDir, $inputName\n";
print "\tInput path ($inputPath) does not exist\n" if (!-f $inputPath);
print "\tTarget dir ($targetDir) does not exist\n" if (!-d $targetDir);
print "\tOutput file ($targetDir\\${inputName}.moc) does not exist\n" if (!-f "$targetDir\\${inputName}.moc");
print "Executing ..\\..\\..\\..\\..\\..\\external\\3rd\\library\\qt\\3.3.4\\bin\\moc -i $inputPath -o $targetDir\\${inputName}.moc\n";
die "Failed while executing command for moc!\n" if (system ("..\\..\\..\\..\\..\\..\\external\\3rd\\library\\qt\\3.3.4\\bin\\moc -i $inputPath -o $targetDir\\${inputName}.moc"));
}
sub processUi
{
# ..\..\..\..\..\..\external\3rd\library\qt\3.3.4\bin\uic -o $(TargetDir)\$(InputName).h $(InputPath) &&
# ..\..\..\..\..\..\external\3rd\library\qt\3.3.4\bin\uic -o $(TargetDir)\$(InputName)_o.cpp -impl $(TargetDir)\$(InputName).h $(InputPath) &&
# ..\..\..\..\..\..\external\3rd\library\qt\3.3.4\bin\moc $(TargetDir)\$(InputName).h >> $(TargetDir)\$(InputName)_o.cpp
die "ui takes 4 arguments: <InputPath> <TargetDir> <InputName> <BuildType>\n" if (@_ != 4);
my $inputPath = shift;
my $targetDir = shift;
my $inputName = shift;
my $buildType = shift;
print "Executing ui for $inputPath, $targetDir, $inputName, $buildType\n";
$buildType = substr(lcfirst $buildType, 0, 1);
print "\tInput path ($inputPath) does not exist\n" if (!-f $inputPath);
print "\tTarget dir ($targetDir) does not exist\n" if (!-d $targetDir);
print "\tOutput header file ($targetDir\\${inputName}.h) does not exist\n" if (!-f "$targetDir\\${inputName}.h");
print "\tOutput cpp file ($targetDir\\${inputName}_${buildType}.cpp) does not exist\n" if (!-f "$targetDir\\${inputName}_${buildType}.cpp");
print "Executing ..\\..\\..\\..\\..\\..\\external\\3rd\\library\\qt\\3.3.4\\bin\\uic -o $targetDir\\$inputName.h $inputPath\n";
die "Failed while executing command 1 for ui!\n" if (system ("..\\..\\..\\..\\..\\..\\external\\3rd\\library\\qt\\3.3.4\\bin\\uic -o $targetDir\\$inputName.h $inputPath"));
print "\tOutput header file ($targetDir\\${inputName}.h) does not exist\n" if (!-f "$targetDir\\${inputName}.h");
print "\tOutput cpp file ($targetDir\\${inputName}_${buildType}.cpp) does not exist\n" if (!-f "$targetDir\\${inputName}_${buildType}.cpp");
print "Executing ..\\..\\..\\..\\..\\..\\external\\3rd\\library\\qt\\3.3.4\\bin\\uic -o $targetDir\\${inputName}_${buildType}.cpp -impl $targetDir\\${inputName}.h $inputPath\n";
die "Failed while executing command 2 for ui!\n" if (system ("..\\..\\..\\..\\..\\..\\external\\3rd\\library\\qt\\3.3.4\\bin\\uic -o $targetDir\\${inputName}_${buildType}.cpp -impl $targetDir\\${inputName}.h $inputPath"));
print "\tOutput header file ($targetDir\\${inputName}.h) does not exist\n" if (!-f "$targetDir\\${inputName}.h");
print "\tOutput cpp file ($targetDir\\${inputName}_${buildType}.cpp) does not exist\n" if (!-f "$targetDir\\${inputName}_${buildType}.cpp");
print "Executing ..\\..\\..\\..\\..\\..\\external\\3rd\\library\\qt\\3.3.4\\bin\\moc $targetDir\\${inputName}.h >> $targetDir\\${inputName}_${buildType}.cpp\n";
die "Failed while executing command 3 for ui!\n" if (system ("..\\..\\..\\..\\..\\..\\external\\3rd\\library\\qt\\3.3.4\\bin\\moc $targetDir\\${inputName}.h >> $targetDir\\${inputName}_${buildType}.cpp"));
}
# ----------------------------------------------------------------------
my $command = shift;
if ($command eq "moc")
{
processMoc(@ARGV);
}
elsif ($command eq "ui")
{
processUi(@ARGV);
}
else
{
print STDERR "Unknown command: $command\n";
usage();
}

View File

@@ -0,0 +1,121 @@
#!/usr/bin/perl
use Digest::MD5 qw(md5_hex);
die "usage: perl buildTreeFileDigest.pl <config_file> <digest_name> [<old_digest_name>]\n" if (scalar(@ARGV) < 2 || scalar(@ARGV) > 3 || $ARGV[0] eq "-h" || $ARGV[0] eq "-?");
$configFile = shift;
$digest = shift;
sub numerically
{
return ($a <=> $b);
}
sub do_directory
{
local $_;
my $base = $_[0];
my $source = $_[1];
my $name = $_[2];
opendir(DIR, $source) || die "could not open source directory $source\n";
my @filenames = readdir(DIR);
closedir(DIR);
for (@filenames)
{
next if ($_ eq "." || $_ eq "..");
if (-d "$source/$_")
{
if ($name eq "")
{
&do_directory($base, "$source/$_", "$_");
}
else
{
&do_directory($base, "$source/$_", "$name/$_");
}
}
else
{
$count += 1;
print "." if ($count % 500 == 0);
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("$source/$_");
my $md5sum = "";
if (defined $old{"$name/$_"})
{
($oldName, $oldPath, $oldSize, $oldTime, $oldDigest) = split(/\s+/, $old{"$name/$_"}, 5);
if ($size == $oldSize && $mtime == $oldTime)
{
$md5sum = $oldDigest;
# print "cached $name/$_ '$md5sum'\n";
}
else
{
# print "changed $name/$_ !($size==$oldSize && $mtime==$oldTime)\n";
}
}
if ($md5sum eq "")
{
my $buffer;
open(FILE, "$source/$_") || die "could not spawn md5sum on file $source/$_";
binmode FILE;
read(FILE, $buffer, -s "$source/$_");
close(FILE);
$md5sum = md5_hex($buffer);
# print "compute $name/$_ $md5sum\n";
}
$files{"$name/$_"} = "$name/$_ $base $size $mtime $md5sum";
}
}
}
if (@ARGV)
{
open(DIGEST, shift) || die "could not open old digest file\n";
while (<DIGEST>)
{
chomp;
($oldName, $oldPath, $oldSize, $oldTime, $oldDigest) = split(/\s+/, $_);
# print "caching $oldName: $_\n";
$old{$oldName} = $_;
}
close(DIGEST);
}
open(CONFIG, $configFile) || die "could not open config file $configFile\n";
while (<CONFIG>)
{
chomp;
if (/searchPath/)
{
s/^.*searchPath//;
s/\s+//;
push(@paths, $_);
}
}
close(CONFIG);
foreach (sort numerically @paths)
{
$count = 0;
($priority, $path) = split(/=/);
print "processing $path($priority)";
do_directory($path, $path, "");
print "\n";
}
open(DIGEST, ">$digest");
foreach (sort keys %files)
{
print DIGEST $files{$_}, "\n";
}
close(DIGEST);

View File

@@ -0,0 +1,11 @@
$what = shift;
while ($a = <>)
{
if ($a =~ /^\s*\d+\s+Error:/)
{
print if (eval $what);
$_ = "";
}
$_ .= $a;
}
print if (eval $what);

View File

@@ -0,0 +1,19 @@
#!/usr/bin/perl
while (<>)
{
if (/^\./)
{
$debug .= $_;
s/\/debug\//\/release\//;
$release .= $_;
}
else
{
$debug .= $_;
$release .= $_;
}
}
print $debug;
print $release;

View File

@@ -0,0 +1,292 @@
#!/usr/bin/perl -w
use File::stat;
###
# Copyright (C)2000-2002 Sony Online Entertainment Inc.
# All Rights Reserved
#
# Title: emailDataLint.pl
# Description: emails datalint generated client files to appropriate people
# @author $Author: gmcdaniel $
# @version $Revision: #4 $
##
#todo Once the command line parameter of where to drop the files is added I can move this script back out of the exe\win32 directory.
#todo Change the taskmanager to point to the new script location once above change happens.
#todo Email may not work unless client does not crash.
##
# This subroutine returns the current local date
sub get_date
{
($day, $month, $year) = (localtime) [3,4,5];
$month = $month + 1;
$year = $year + 1900;
$date = $month."/".$day."/".$year;
return $date;
} # End of sub get_date
##
# This subroutine checks for warnings and errors in the datalint txt files. If there is an error it returns true otherwise it returns false.
# It takes the name of the txt file to check as input.
sub Check_Logfile_For_Warnings_and_Errors
{
$second_to_last_line = "current_line_2";
open (Logfile,"C:\\$work_path\\swg\\test\\exe\\win32\\$_[0].txt") || die "Cannot open $_[0] for reading.";
while (<Logfile>)
{
chomp;
$second_to_last_line = $_;
}
close (Logfile) || die "can't close $_[0]";
print ("\n");
if ($second_to_last_line eq "current_line_2")
{
print ("No warnings or fatals found in $_[0]\n");
print ("\n");
return "false";
}
else
{
print ("Warnings or errors found in $_[0]\n");
print ("\n");
return "true";
}
} # End of sub Check_Logfile_For_Warnings_and_Errors
##
# This subroutine checks for the existance of errors and fatals in the datalint logs. The logs are then sent to the appropriate people.
# It takes the name of the logfile to check and a string with the list if email addresses to mail if there are errors.
sub check_and_email_datalint_logs
{
$date_stamp = get_date();
$Error = Check_Logfile_For_Warnings_and_Errors($_[0]);
if ($Error eq "true")
{
#Check size of file to see if it should be zipped or not
$LogFile="C:\\$work_path\\swg\\test\\exe\\win32\\$_[0].txt";
$info=stat($LogFile);
$sizeOfFile = $info->size;
if ($sizeOfFile < 512)
{
print ("Error or warning found in $_[0]. Emailing appropriate people.\n");
system ("c:\\postie\\postie -host:mail-sd.station.sony.com $_[1] -from:$gmcdaniel -s:\"[DataLint] Errors or Warnings in $_[0] $date_stamp\" -msg:\"Attached is $_[0] listing the asset warnings and errors as found by DataLint. Let me know if you have any questions. Thanks,Grant\" -a:c:\\$work_path\\swg\\test\\exe\\win32\\$_[0].txt");
}
else
{
print ("Error or warning found in $_[0]. Emailing appropriate people.\n");
print ("File to large to send, zipping");
system ("c:\\progra~1\\winzip\\wzzip.exe c:\\$work_path\\swg\\test\\exe\\win32\\$_[0].zip $LogFile");
system ("c:\\postie\\postie -host:mail-sd.station.sony.com $_[1] -from:$gmcdaniel -s:\"[DataLint] Errors or Warnings in $_[0] $date_stamp\" -msg:\"Attached is $_[0] listing the asset warnings and errors as found by DataLint. Let me know if you have any questions. Thanks,Grant\" -a:c:\\$work_path\\swg\\test\\exe\\win32\\$_[0].zip");
}
}
else
{
print ("No errors or warnings found in $_[0].");
system ("c:\\postie\\postie -host:mail-sd.station.sony.com $gmcdaniel -from:$gmcdaniel -s:\"[DataLint] $_[0] $date_stamp\" -nomsg -a:c:\\$work_path\\swg\\test\\exe\\win32\\$_[0].txt");
}
} # End of sub check_and_email_datalint_logs
########## MAIN ##########
$work_path = "workpublish";
##
# Runs DataLintRspBuilder and DataLint
print ("Beginning DataLintRspBuilder...\n");
#system ("copy c:\\work\\swg\\test\\tools\\DataLintRspBuilder.exe c:\\$work_path\\swg\\test\\exe\\win32\\DataLintRspBuilder.exe");
#system ("c:\\$work_path\\swg\\test\\exe\\win32\\DataLintRspBuilder.exe c:\\$work_path\\swg\\test\\exe\\win32\\common.cfg");
print ("DataLintRspBuilder Complete\n");
print ("\n");
print ("\n");
print ("Beginning DataLint...\n");
#system ("c:\\$work_path\\swg\\test\\exe\\win32\\SwgClient_d.exe -- -s DataLint disable=0 -s SharedFoundation demo Mode=1");
print ("DataLint Complete\n");
print ("\n");
print ("\n");
#
## End of Runs DataLintRspBuilder and DataLint
## Check_For_Warnings_and_Errors
#
print ("Checking for errors and warnings...\n");
print ("\n");
# Email addresses
$gmcdaniel = "gmcdaniel\@soe.sony.com";
$jbrack = "jbrack\@soe.sony.com";
$jgrills = "jgrills\@soe.sony.com";
$asommers = "asommers\@soe.sony.com";
$cmayer = "cmayer\@soe.sony.com";
$jrodgers = "jrodgers\@soe.sony.com";
$jroy = "jroy\@soe.sony.com";
$jshoopack = "jshoopack\@soe.sony.com";
#$acastoro = "acastoro\@soe.sony.com";
$cbarnes = "cbarnes\@soe.sony.com";
$rkoster = "rkoster\@soe.sony.com";
$jdonham = "jdonham\@soe.sony.com";
$rvogel = "rvogel\@soe.sony.com";
$mhigby = "mhigby\@soe.sony.com";
$ssnopel = "ssnopel\@soe.sony.com";
$jwhisenant = "jwhisenant\@soe.sony.com";
$swo_leads = "-to:$cmayer -to:$asommers -to:$jgrills -to:$jrodgers -to:$jroy -to:$jshoopack -to:$cbarnes -to:$rkoster -cc:$gmcdaniel -cc:$jbrack -cc:$jdonham -cc:$rvogel -cc:$ssnopel -cc:$jwhisenant";
$prog_leads = "-to:$cmayer -to:$asommers -to:$jgrills -cc:$gmcdaniel -cc:$jbrack -cc:$ssnopel -cc:$jwhisenant";
$art_leads = "-to:$jrodgers -to:$jroy -to:$jshoopack -cc:$gmcdaniel -cc:$jbrack -cc:$ssnopel -cc:$jwhisenant";
$design_leads = "-to:$cbarnes -to:$rkoster -cc:$gmcdaniel -cc:$jbrack -cc:$ssnopel -cc:$jwhisenant";
$art_and_design_leads = "-to:$cbarnes -to:$rkoster -to:$jrodgers -to:$jroy -to:$jshoopack -cc:$gmcdaniel -cc:$jbrack -cc:$ssnopel -cc:$jwhisenant";
$qa_leads = "-to:$gmcdaniel -to:$ssnopel -to:$jwhisenant";
check_and_email_datalint_logs("DataLint_Errors_All",$swo_leads);
check_and_email_datalint_logs("DataLint_Errors_All_Fatal",$swo_leads);
check_and_email_datalint_logs("DataLint_Errors_Appearance",$art_leads);
check_and_email_datalint_logs("DataLint_Errors_ArrangementDescriptor",$art_and_design_leads);
check_and_email_datalint_logs("DataLint_Errors_LocalizedStringTable",$design_leads);
check_and_email_datalint_logs("DataLint_Errors_ObjectTemplate",$design_leads);
check_and_email_datalint_logs("DataLint_Errors_PortalProperty",$art_leads);
check_and_email_datalint_logs("DataLint_Errors_ShaderTemplate",$art_leads);
check_and_email_datalint_logs("DataLint_Errors_SkyBox",$art_leads);
check_and_email_datalint_logs("DataLint_Errors_SlotDescriptor",$art_and_design_leads);
check_and_email_datalint_logs("DataLint_Errors_SoundTemplate",$prog_leads);
check_and_email_datalint_logs("DataLint_Errors_Texture",$art_leads);
check_and_email_datalint_logs("DataLint_Errors_TextureRenderer",$art_leads);
# Checks for content in DataLint_UnsupportedAssets.txt and sends appropriate email
#todo this should probably not be daily
$Logfile_to_check = "DataLint_UnsupportedAssets";
print ("Checking $Logfile_to_check for contents...\n");
$Error = Check_Logfile_For_Warnings_and_Errors($Logfile_to_check);
if ($Error eq "true")
{
#Check size of file to see if it should be zipped or not
$LogFile="C:\\$work_path\\swg\\test\\exe\\win32\\$Logfile_to_check.txt";
$info=stat($LogFile);
$sizeOfFile = $info->size;
if ($sizeOfFile < 512)
{
print ("Contents found in $Logfile_to_check. Emailing appropriate people.\n");
system ("c:\\postie\\postie -host:mail-sd.station.sony.com $prog_leads -from:$gmcdaniel -s:\"Unsupported Assets in $Logfile_to_check $date_stamp\" -nomsg -a:c:\\$work_path\\swg\\test\\exe\\win32\\$Logfile_to_check.txt");
}
else
{
print ("Contents found in $Logfile_to_check. Emailing appropriate people.\n");
print ("File to large to send, zipping");
system ("c:\\progra~1\\winzip\\wzzip.exe c:\\$work_path\\swg\\test\\exe\\win32\\DataLint_UnsupportedAssets.zip $LogFile");
system ("c:\\postie\\postie -host:mail-sd.station.sony.com $prog_leads -from:$gmcdaniel -s:\"Unsupported Assets in $Logfile_to_check $date_stamp\" -nomsg -a:c:\\$work_path\\swg\\test\\exe\\win32\\$Logfile_to_check.zip");
}
}
else
{
print ("No contents in $Logfile_to_check.");
#todo Should eventually not email anyone with the results.
system ("c:\\postie\\postie -host:mail-sd.station.sony.com -to:$gmcdaniel -from:$gmcdaniel -s:\"$Logfile_to_check $date_stamp\" -nomsg -a:c:\\$work_path\\swg\\test\\exe\\win32\\$Logfile_to_check");
}
print ("End of errors and warnings check for DataLint files.\n");
print ("\n");
#
## End of Check_For_Warnings_and_Errors
########## END OF MAIN ##########

View File

@@ -0,0 +1,227 @@
#!/usr/bin/perl -w
use File::stat;
###
# Copyright (C)2000-2002 Sony Online Entertainment Inc.
# All Rights Reserved
#
# Title: emailDataLint.pl
# Description: emails datalint generated server files to appropriate people
# @author $Author: gmcdaniel $
# @version $Revision: #1 $
##
#todo Once the command line parameter of where to drop the files is added I can move this script back out of the exe\win32 directory.
#todo Change the taskmanager to point to the new script location once above change happens.
#todo Email may not work unless client does not crash.
##
# This subroutine returns the current local date
sub get_date
{
($day, $month, $year) = (localtime) [3,4,5];
$month = $month + 1;
$year = $year + 1900;
$date = $month."/".$day."/".$year;
return $date;
} # End of sub get_date
##
# This subroutine checks for warnings and errors in the datalint txt files. If there is an error it returns true otherwise it returns false.
# It takes the name of the txt file to check as input.
sub Check_Logfile_For_Warnings_and_Errors
{
$second_to_last_line = "current_line_2";
open (Logfile,"C:\\$work_path\\swg\\test\\exe\\win32\\$_[0].txt") || die "Cannot open $_[0] for reading.";
while (<Logfile>)
{
chomp;
$second_to_last_line = $_;
}
close (Logfile) || die "can't close $_[0]";
print ("\n");
if ($second_to_last_line eq "current_line_2")
{
print ("No warnings or fatals found in $_[0]\n");
print ("\n");
return "false";
}
else
{
print ("Warnings or errors found in $_[0]\n");
print ("\n");
return "true";
}
} # End of sub Check_Logfile_For_Warnings_and_Errors
##
# This subroutine checks for the existance of errors and fatals in the datalint logs. The logs are then sent to the appropriate people.
# It takes the name of the logfile to check and a string with the list if email addresses to mail if there are errors.
sub check_and_email_datalint_logs
{
$date_stamp = get_date();
$Error = Check_Logfile_For_Warnings_and_Errors($_[0]);
if ($Error eq "true")
{
#Check size of file to see if it should be zipped or not
$LogFile="C:\\$work_path\\swg\\test\\exe\\win32\\$_[0].txt";
$info=stat($LogFile);
$sizeOfFile = $info->size;
if ($sizeOfFile < 512)
{
print ("Error or warning found in $_[0]. Emailing appropriate people.\n");
system ("c:\\postie\\postie -host:mail-sd.station.sony.com $_[1] -from:$gmcdaniel -s:\"[DataLint] Errors or Warnings in $_[0] $date_stamp\" -msg:\"Attached is $_[0] listing the asset warnings and errors as found by DataLint. Let me know if you have any questions. Thanks,Grant\" -a:c:\\$work_path\\swg\\test\\exe\\win32\\$_[0].txt");
}
else
{
print ("Error or warning found in $_[0]. Emailing appropriate people.\n");
print ("File to large to send, zipping");
system ("c:\\progra~1\\winzip\\wzzip.exe c:\\$work_path\\swg\\test\\exe\\win32\\$_[0].zip $LogFile");
system ("c:\\postie\\postie -host:mail-sd.station.sony.com $_[1] -from:$gmcdaniel -s:\"[DataLint] Errors or Warnings in $_[0] $date_stamp\" -msg:\"Attached is $_[0] listing the asset warnings and errors as found by DataLint. Let me know if you have any questions. Thanks,Grant\" -a:c:\\$work_path\\swg\\test\\exe\\win32\\$_[0].zip");
}
}
else
{
print ("No errors or warnings found in $_[0].");
system ("c:\\postie\\postie -host:mail-sd.station.sony.com $gmcdaniel -from:$gmcdaniel -s:\"[DataLint] $_[0] $date_stamp\" -nomsg -a:c:\\$work_path\\swg\\test\\exe\\win32\\$_[0].txt");
}
} # End of sub check_and_email_datalint_logs
########## MAIN ##########
$work_path = "workpublish";
##
# Runs DataLintRspBuilder and DataLint
print ("Beginning DataLintRspBuilder...\n");
#system ("copy c:\\work\\swg\\test\\tools\\DataLintRspBuilder.exe c:\\$work_path\\swg\\test\\exe\\win32\\DataLintRspBuilder.exe");
#system ("c:\\$work_path\\swg\\test\\exe\\win32\\DataLintRspBuilder.exe c:\\$work_path\\swg\\test\\exe\\win32\\common.cfg");
print ("DataLintRspBuilder Complete\n");
print ("\n");
print ("\n");
print ("Beginning DataLint...\n");
#system ("c:\\$work_path\\swg\\test\\exe\\win32\\SwgClient_d.exe -- -s DataLint disable=0 -s SharedFoundation demo Mode=1");
print ("DataLint Complete\n");
print ("\n");
print ("\n");
#
## End of Runs DataLintRspBuilder and DataLint
## Check_For_Warnings_and_Errors
#
print ("Checking for errors and warnings...\n");
print ("\n");
# Email addresses
$gmcdaniel = "gmcdaniel\@soe.sony.com";
$jbrack = "jbrack\@soe.sony.com";
$jgrills = "jgrills\@soe.sony.com";
$asommers = "asommers\@soe.sony.com";
$cmayer = "cmayer\@soe.sony.com";
$jrodgers = "jrodgers\@soe.sony.com";
$jroy = "jroy\@soe.sony.com";
$jshoopack = "jshoopack\@soe.sony.com";
#$acastoro = "acastoro\@soe.sony.com";
$cbarnes = "cbarnes\@soe.sony.com";
$rkoster = "rkoster\@soe.sony.com";
$jdonham = "jdonham\@soe.sony.com";
$rvogel = "rvogel\@soe.sony.com";
$mhigby = "mhigby\@soe.sony.com";
$ssnopel = "ssnopel\@soe.sony.com";
$jwhisenant = "jwhisenant\@soe.sony.com";
$swo_leads = "-to:$cmayer -to:$asommers -to:$jgrills -to:$jrodgers -to:$jroy -to:$jshoopack -to:$cbarnes -to:$rkoster -cc:$gmcdaniel -cc:$jbrack -cc:$jdonham -cc:$rvogel -cc:$ssnopel -cc:$jwhisenant";
$prog_leads = "-to:$cmayer -to:$asommers -to:$jgrills -cc:$gmcdaniel -cc:$jbrack -cc:$ssnopel -cc:$jwhisenant";
$art_leads = "-to:$jrodgers -to:$jroy -to:$jshoopack -cc:$gmcdaniel -cc:$jbrack -cc:$ssnopel -cc:$jwhisenant";
$design_leads = "-to:$cbarnes -to:$rkoster -cc:$gmcdaniel -cc:$jbrack -cc:$ssnopel -cc:$jwhisenant";
$art_and_design_leads = "-to:$cbarnes -to:$rkoster -to:$jrodgers -to:$jroy -to:$jshoopack -cc:$gmcdaniel -cc:$jbrack -cc:$ssnopel -cc:$jwhisenant";
$qa_leads = "-to:$gmcdaniel -to:$ssnopel -to:$jwhisenant";
check_and_email_datalint_logs("DataLintServer_Errors_All",$swo_leads);
check_and_email_datalint_logs("DataLintServer_Errors_All_Fatal",$swo_leads);
check_and_email_datalint_logs("DataLintServer_Errors_ObjectTemplate",$design_leads);
print ("End of errors and warnings check for DataLint files.\n");
print ("\n");
#
## End of Check_For_Warnings_and_Errors
########## END OF MAIN ##########

View File

@@ -0,0 +1,121 @@
use warnings;
use strict;
use Compress::Zlib;
sub numerically
{
return $a <=> $b;
}
die "usage: $0 changelist [changelist ...]" if (@ARGV == 0 || $ARGV[0] =~ /^[-\/]/);
my $debug = 0;
my %size;
my %files;
foreach my $changelist (sort numerically @ARGV)
{
print STDERR "describing $changelist\n" if ($debug);
open(P4, "p4 -ztag describe -s $changelist|") || die "could not describe $changelist\n";
my $depotFile;
while (<P4>)
{
chomp;
if (s/^\.\.\. depotFile\d+ //)
{
$depotFile = $_ if (m%/data/%);
}
elsif (defined $depotFile && s/^\.\.\. action\d+ //)
{
if ($_ eq "delete")
{
print " ", $depotFile, " **DELETED**\n" if ($debug);
delete $files{$depotFile} if defined($files{$depotFile});
undef $depotFile;
}
}
elsif (defined $depotFile && s/^\.\.\. rev\d+ //)
{
$files{$depotFile} = $_;
print " ", $depotFile, "#", $_, "\n" if ($debug);
undef $depotFile;
}
}
close(P4);
}
my @files = sort keys %files;
die "no files to patch in changelists\n" if (@files== 0);
print STDERR "syncing\n" if ($debug);
open(P4, "| p4 -x - sync 2> nul");
foreach (@files)
{
print P4 " ", $_, "#", $files{$_}, "\n";
}
close(P4);
print STDERR "fstat\n" if ($debug);
foreach my $file (@files)
{
print STDERR " fstat $file\n" if ($debug);
open(P4, "p4 fstat $file |") || die "could not fstat $file\n";
while (<P4>)
{
chomp;
if (s/^\.\.\. clientFile //)
{
my $size = -s $_;
if (/\.wav$/ || /\.mp3$/)
{
# wav and mp3 files remain uncompressed
$size{$_} = $size;
}
else
{
print STDERR " reading $file\n" if ($debug);
my $contents;
open(FILE, $_) || die "could not open file $_\n";
binmode FILE;
read(FILE, $contents, $size);
close(FILE);
print STDERR " compressing $file\n" if ($debug);
my $compressor = deflateInit();
my $compressed = $compressor->deflate($contents);
$compressed .= $compressor->flush();
$size{$_} = (length($compressed) < $size) ? length($compressed) : $size;
}
}
}
close(P4);
}
# total up the output
my $total = 0;
my $count = 0;
foreach (keys %size)
{
$total += $size{$_};
++$count;
}
# choose the appropriate units for the output
my $extension = "bytes";
my $format = "%0.0f";
if ($total > 1024)
{
$extension = "kb";
$total /= 1024;
$format = "%0.2f";
}
if ($total > 1024)
{
$extension = "mb";
$total /= 1024;
}
print "estimate patch size ", sprintf($format, $total), " $extension ($count files)\n";

View File

@@ -0,0 +1,435 @@
#! /usr/bin/perl
# ======================================================================
#
# ======================================================================
use strict;
use warnings;
use POSIX qw(ceil);
# ======================================================================
# Globals
# ======================================================================
my $scriptName = $0;
my $absoluteScriptName = $scriptName;
$scriptName =~ s/^(.*)[\\\/]//;
my $inputFile;
my $outputFile;
my @simulation;
my $template =
qq%# Use pound to comment
Label: <simulation label>
NumberOfRounds: <num rounds>
CombatConsts:
BaseToHit: <base to hit>
MaxToHit: <max to hit>
MinToHit: <min to hit>
ToHitScale: <to hit scale>
ToHitStep: <to hit step>
DamageScale: <damage scale>
Attacker:
Stats:
AttackValue: <attack value>
CombatSkillMods:
SpeedMod: <speed value>
WeaponStats:
RateOfFire: <rate of fire>
MaxDamage: <max damage>
MinDamage: <min damage>
Defender:
Stats:
DefenseValue: <defense value>
ArmorStats:
Effectiveness: <armor value>
IncrementAttribute:
Attribute: <attribute>
IncrementValue: <increment value>
MaxValue: <max>
End:
# You can put multiple of these entries in one file, but each must end with End:
%;
# ======================================================================
# Combat consts
# ======================================================================
use constant DEFAULT_BASE_TO_HIT => 90.0;
use constant DEFAULT_MAX_TO_HIT => 95.0;
use constant DEFAULT_MIN_TO_HIT => 60.0;
use constant DEFAULT_TO_HIT_SCALE => 50.0;
use constant DEFAULT_TO_HIT_STEP => 5.0;
use constant DEFAULT_DAMAGE_SCALE => 500.0;
# ======================================================================
# Subroutines
# ======================================================================
sub usage()
{
die "\nUsage:\n\t$scriptName <input file>\n\n".
"\t$scriptName --template <file name> : will dump out a template file for the input\n";
}
sub calculateHit
{
my $hashRef = $_[0];
my $success = 0;
my $damage = 0;
my $baseToHit = (exists $hashRef->{"CombatConsts"}->{"BaseToHit"}) ? $hashRef->{"CombatConsts"}->{"BaseToHit"} : DEFAULT_BASE_TO_HIT;
my $maxToHit = (exists $hashRef->{"CombatConsts"}->{"MaxToHit"}) ? $hashRef->{"CombatConsts"}->{"MaxToHit"} : DEFAULT_MAX_TO_HIT;
my $minToHit = (exists $hashRef->{"CombatConsts"}->{"MinToHit"}) ? $hashRef->{"CombatConsts"}->{"MinToHit"} : DEFAULT_MIN_TO_HIT;
my $toHitScale = (exists $hashRef->{"CombatConsts"}->{"ToHitScale"}) ? $hashRef->{"CombatConsts"}->{"ToHitScale"} : DEFAULT_TO_HIT_SCALE;
my $toHitStep = (exists $hashRef->{"CombatConsts"}->{"ToHitStep"}) ? $hashRef->{"CombatConsts"}->{"ToHitStep"} : DEFAULT_TO_HIT_STEP;
my $damageScale = (exists $hashRef->{"CombatConsts"}->{"DamageScale"}) ? $hashRef->{"CombatConsts"}->{"DamageScale"} : DEFAULT_DAMAGE_SCALE;
# ----- START BASE RESOLUTION FORMULA -----
my $attackVal = $hashRef->{"Attacker"}->{"Stats"}->{"AttackValue"} - $hashRef->{"Defender"}->{"Stats"}->{"DefenseValue"};
my $resultAttackVal = $attackVal;
$attackVal /= $toHitScale;
my $stepDir = 0.0;
if ($attackVal > $stepDir)
{
$stepDir = 1.0;
}
elsif ($attackVal < $stepDir)
{
$stepDir = -1.0;
}
my $toHitChance = $baseToHit;
my $maxStep = ceil(($baseToHit - $minToHit)/$toHitStep);
for (my $i = 1; $i < $maxStep; $i++)
{
if (($attackVal * $stepDir) > $i)
{
$toHitChance += $stepDir * $toHitStep;
$attackVal -= $stepDir * $i;
}
else
{
$toHitChance += ($attackVal/$i) * $toHitStep;
last;
}
}
$toHitChance = $maxToHit if ($toHitChance > $maxToHit);
$toHitChance = $minToHit if ($toHitChance < $minToHit);
if ((rand(99.0) + 1) < $toHitChance)
{
$success = 1;
my $dist = 0.5 + ($resultAttackVal / $damageScale);
$damage = distributedRand($hashRef->{"Attacker"}->{"WeaponStats"}->{"MinDamage"}, $hashRef->{"Attacker"}->{"WeaponStats"}->{"MaxDamage"}, $dist);
}
my @result = ($success, $damage);
return @result;
# ----- END BASE RESOLUTION FORMULA -----
}
sub distributedRand
{
my ($min, $max, $dist) = @_;
my $inverted = 0;
my $_min = $min;
my $_max = $max;
$dist = -1 if ($dist < -1);
$dist = 2 if ($dist > 2);
if ($min > $max)
{
$inverted = 1;
$min = $_max;
$max = $_min;
}
my $mid = $min + (($max - $min) * $dist);
if ($mid < $min) { $max += ($mid-$min); $mid = $min; }
if ($mid > $max) { $min += ($mid-$max); $mid = $max; }
my $minRand = (rand(int($mid+0.5) - $min) + $min);
my $maxRand = (rand($max - int($mid+0.5)) + int($mid+0.5));
my $randNum = (rand($maxRand - $minRand) + $minRand);
$randNum = $_min + ($_max - $randNum) if ($inverted);
return $randNum;
}
sub specialCombatSort
{
my ($a, $b) = @_;
return -1 if ($a eq "Label");
return 1 if ($b eq "Label");
return -1 if ($a eq "NumberOfRounds");
return 1 if ($b eq "NumberOfRounds");
return -1 if ($a eq "Attacker");
return 1 if ($b eq "Attacker");
return -1 if ($a eq "Defender");
return 1 if ($b eq "Defender");
return $a cmp $b;
}
sub printHash
{
my ($hashRef, $handle, $tab) = @_;
foreach my $key (sort { specialCombatSort($a, $b) } keys %{$hashRef})
{
if (ref($$hashRef{$key}) eq "HASH")
{
print $handle "$tab$key\n";
printHash($$hashRef{$key}, $handle, "$tab\t");
}
else
{
print $handle "$tab$key: $$hashRef{$key}\n";
}
}
}
sub getFromHash
{
my ($key, $hashRef) = @_;
my $subKey;
$key .= ":" if ($key !~ /:$/);
while ($key)
{
$key =~ s/^([^:\s]+)://;
$subKey = $1;
last if ($key eq "");
$$hashRef{$subKey} = {} if (!exists $$hashRef{$subKey});
$hashRef = $$hashRef{$subKey};
}
return undef if (!exists $$hashRef{$subKey});
return $$hashRef{$subKey};
}
sub putIntoHash
{
my ($key, $val, $hashRef) = @_;
my $subKey;
$key .= ":" if ($key !~ /:$/);
while ($key)
{
$key =~ s/^([^:\s]+)://;
$subKey = $1;
last if ($key eq "");
$$hashRef{$subKey} = {} if (!exists $$hashRef{$subKey});
$hashRef = $$hashRef{$subKey};
}
if (!defined $val || $val eq "")
{
$$hashRef{$subKey} = {};
}
else
{
$$hashRef{$subKey} = $val;
}
}
sub parseInput
{
my $current = "";
my $line = 0;
push @simulation, {};
my @currentLabel;
open(INPUTFILE, $inputFile) || die "cannot open $inputFile\n";
while (<INPUTFILE>)
{
++$line;
# skip whitespace and comments
next if (/^\s+$/ || /^\s*#/);
if (/End:/i)
{
push @simulation, {};
next;
}
s/^(\s*)(\S+):\s*(.*)//;
my $tabs = $1;
my $label = $2;
my $value = $3;
die "Lines must be led with tabs\n" if ($tabs !~ /^\t*$/);
my $tabNum = length $tabs;
if ($tabNum == @currentLabel)
{
push @currentLabel, $label;
}
elsif ($tabNum < @currentLabel)
{
while ($tabNum < @currentLabel)
{
pop @currentLabel;
}
push @currentLabel, $label;
}
else
{
die "Error in input at line $line\n";
}
my $key = (join ":", @currentLabel);
putIntoHash($key, $value, $simulation[$#simulation]);
}
close(INPUTFILE);
# for extra hash ref at the end
pop @simulation;
}
sub printHeader
{
my $hashRef = $_[0];
printHash($hashRef, *OUTPUT);
print OUTPUT "\n";
# grab the resolution formula and put it in, too
my $foundResolution = 0;
print OUTPUT "BaseResolutionFormula\n";
open (SCRIPT, $absoluteScriptName) || die "Can't open own script\n";
while (<SCRIPT>)
{
last if (/----- END BASE RESOLUTION FORMULA -----/);
print OUTPUT "\t$_" if ($foundResolution);
$foundResolution = 1 if (/----- START BASE RESOLUTION FORMULA -----/);
}
close (SCRIPT);
print OUTPUT "\n";
print OUTPUT join("\t", "Time Stamp", "Hit?", "Base Damage", "Damage Reduction", "Net Damage", "Running DPS", "Running DPM", "Running Hit Rate", "Total Damage Done"), "\n";
}
# ======================================================================
# Main
# ======================================================================
if (@ARGV == 2 && $ARGV[0] =~ /--template/i)
{
shift;
my $templateFile = shift;
open (TEMPLATE, ">$templateFile") || die "cannot open $templateFile\n";
print TEMPLATE $template;
close (TEMPLATE);
die "Created template.\n";
}
usage() if (@ARGV != 1);
$inputFile = shift;
parseInput();
while (@simulation)
{
my @summaryInfo;
my $hashRef = shift @simulation;
print "Running simulation for ", $hashRef->{"Label"}, "\n";
$outputFile = "FOMCS_";
$outputFile .= $hashRef->{"Label"};
$outputFile =~ s/\s+/_/g;
open (OUTPUT, ">$outputFile.detailed") || die "cannot open $outputFile.detailed for output\n";
printHeader($hashRef);
my $incrementAttribute = (exists $hashRef->{"IncrementAttribute"}->{"Attribute"}) ? $hashRef->{"IncrementAttribute"}->{"Attribute"} : "";
my $incrementValue = (exists $hashRef->{"IncrementAttribute"}->{"IncrementValue"}) ? $hashRef->{"IncrementAttribute"}->{"IncrementValue"} : 0;
my $maxValue = (exists $hashRef->{"IncrementAttribute"}->{"MaxValue"}) ? $hashRef->{"IncrementAttribute"}->{"MaxValue"} : 1;
my $tick = $hashRef->{"Attacker"}->{"WeaponStats"}->{"RateOfFire"};
die "Cannot find $incrementAttribute in input!\n" if ($incrementAttribute ne "" && !defined getFromHash($incrementAttribute, $hashRef));
while (1)
{
my $timeStamp = 0;
my $damageTotal = 0;
my $hitRate = 0;
push @summaryInfo, [getFromHash($incrementAttribute, $hashRef), 0, 0, 0, 0, 0, 0, 0] if ($incrementAttribute ne "");
for (my $simNum = 1; $simNum <= $hashRef->{"NumberOfRounds"}; $simNum++)
{
my @hit = calculateHit($hashRef);
my $oldTime = $timeStamp;
# calculate any necessary speed mods
my $speedMod = (exists $hashRef->{"Attacker"}->{"CombatSkillMods"}->{"SpeedMod"}) ? $hashRef->{"Attacker"}->{"CombatSkillMods"}->{"SpeedMod"} : 0;
my $basePower = 0.985;
my $scale = 1.1;
$timeStamp += ($tick * ((($basePower**$speedMod) + $scale) / ($scale + 1.0)));
++$hitRate if ($hit[0]);
$damageTotal += $hit[1];
my $armorReduction = ($hit[1] * ($hashRef->{"Defender"}->{"ArmorStats"}->{"Effectiveness"} / 10000.0));
print OUTPUT join("\t", $oldTime, $hit[0], $hit[1], $armorReduction, ($hit[1] - $armorReduction), ($damageTotal / $timeStamp), ($damageTotal / $timeStamp / 60.0), ($hitRate / $simNum), $damageTotal), "\n";
if ($incrementAttribute ne "")
{
$summaryInfo[$#summaryInfo]->[1] += ($hit[1] / $hashRef->{"NumberOfRounds"});
$summaryInfo[$#summaryInfo]->[2] += ($armorReduction / $hashRef->{"NumberOfRounds"});
$summaryInfo[$#summaryInfo]->[3] += (($hit[1] - $armorReduction) / $hashRef->{"NumberOfRounds"});
if ($simNum == $hashRef->{"NumberOfRounds"})
{
$summaryInfo[$#summaryInfo]->[4] = ($damageTotal / $timeStamp);
$summaryInfo[$#summaryInfo]->[5] = ($damageTotal / $timeStamp / 60.0);
$summaryInfo[$#summaryInfo]->[6] = ($hitRate / $simNum);
$summaryInfo[$#summaryInfo]->[7] = $damageTotal;
}
}
}
print OUTPUT "\n";
last if ($incrementAttribute eq "");
print "Completed for $incrementAttribute ", getFromHash($incrementAttribute, $hashRef), "\n";
if (getFromHash($incrementAttribute, $hashRef) <= ($maxValue - $incrementValue))
{
putIntoHash($incrementAttribute, ($incrementValue + getFromHash($incrementAttribute, $hashRef)), $hashRef);
}
else
{
last;
}
}
close (OUTPUT);
print "\n";
if ($incrementAttribute ne "")
{
# output the summary
open (SUMMARY, ">$outputFile.summary") || die "Cannot open $outputFile.summary\n";
print SUMMARY join("\t", $incrementAttribute, "Av. Base Damage", "Av. Damage Red.", "Av. Net Damage", "DPS", "DPM", "Hit Rate", "Total Damage"), "\n";
foreach my $elem (@summaryInfo)
{
print SUMMARY (join "\t", @{$elem}), "\n";
}
close (SUMMARY);
}
}
print "Done.\n";

View File

@@ -0,0 +1,73 @@
#!/usr/bin/perl
sub usage
{
}
sub numerically
{
return -($a <=> $b);
}
while (<>)
{
s/\s+/ /;
chomp;
foreach $compare (keys %warnings)
{
@current = split(/\s+/, $_);
@compare = split(/\s+/, $compare);
if (scalar(@current) == scalar(@compare))
{
$count = 0;
$out = "";
while (@current)
{
$a = shift @current;
$b = shift @compare;
if ($a eq $b)
{
$out .= " $a";
}
else
{
$out .= " XXXX";
$count += 1;
}
}
if ($count <= $similar)
{
$out =~ s/^ //;
if ($warnings{$out} ne $warnings{$compare})
{
$warnings{$out} = $warnings{$compare};
delete $warnings{$compare};
}
$_ = $out;
}
else
{
}
}
}
$warnings{$_} += 1 if ($repeat == 0)
}
foreach (keys %warnings)
{
push(@warnings, sprintf("%5d %s", $warnings{$_}, $_));
}
foreach (sort numerically @warnings)
{
print $_, "\n";
}

View File

@@ -0,0 +1,317 @@
#!/usr/bin/perl
use strict;
use warnings;
use perllib::Iff;
# Things to look for:
#
# object templates
# forceNoCollision
#
# appearance templtaes
# FORM 0003
# Extents
# NULL collision extent means not collideable
# 1163416400 - EXSP
# 1163412056 - EXBX
# 1480808780 - XCYL
# 1129140308 - CMPT
# 1146372428 - DTAL
# 1129141064 - CMSH
# 1314212940 - NULL
#
# Path:
# objectTemplate (probably have to go up heirarchy / shared)
# - scan for forceNoCollision
# - scan for appearanceTemplate (server side)
# appearanceTemplate
# - scan for ssa
# serverSideAppearance
# - scan for collision extent
use constant DEBUG => 1;
use constant UNTESTED => -1;
use constant NOT_COLLIDEABLE => 0;
use constant COLLIDEABLE => 1;
sub usage
{
die "\n\tfindAllCollideableObjects.pl <branch>\n\n";
}
usage if (!@ARGV);
my $branch = shift;
my $branchDir = "";
open (P4, "p4 -ztag where //depot/swg/$branch/... |") || die "Can't run p4 where for $branch\n";
while (<P4>)
{
$branchDir = $1 if (m!\.\.\. path (\S+)[\\\/]\.\.\.!);
}
close (P4);
$branchDir =~ s![\\\/]+!/!g;
my %appearanceTemplates;
my %objectTemplates;
print "\nBuilding list of all object templates...\n";
open (P4, "p4 files //depot/swg/$branch/dsrc/*/sys.s*/compiled/game/object/... |") || die "Can't run p4 files for $branch\n";
while (<P4>)
{
next if (/ - delete/);
chomp;
s!\#.*$!!;
# element maps to : [ <absolute path>, <collideable> ]
my $path = $_;
$path =~ s!//depot/swg/$branch/!$branchDir/!;
$_ =~ s!^.*/dsrc/sku[^\\\/]+/sys[^\\\/]+/compiled/game/!!;
$objectTemplates{$_} = [$path, UNTESTED];
}
close (P4);
print "\nBuilding list of all appearance files...\n";
open (P4, "p4 files //depot/swg/$branch/data/*/sys.*/.../appearance/... |") || die "Can't run p4 files for $branch\n";
while (<P4>)
{
next if (/ - delete/);
chomp;
s!\#.*$!!;
my $path = $_;
$path =~ s!//depot/swg/$branch/!$branchDir/!;
$_ =~ s!^.*/data/sku[^\\\/]+/sys[^\\\/]+/[^\\\/]+/[^\\\/]+/!!;
$appearanceTemplates{$_} = [$path, UNTESTED];
}
close (P4);
print "\nScanning all object templates...\n";
foreach my $objectTemplate (sort keys %objectTemplates)
{
# skip this element if we've tested it
next if ($objectTemplates{$objectTemplate}->[1] != UNTESTED);
if ($objectTemplate =~ m!/base/! || $objectTemplate =~ m!/base/!)
{
print "$objectTemplate : not collideable : because it's a base object\n" if (DEBUG);
$objectTemplates{$objectTemplate}->[1] = NOT_COLLIDEABLE;
next;
}
if ($objectTemplate =~ m!\.(btm)|(me)|(txt)!)
{
print "$objectTemplate : not collideable : because it's a file I don't care about\n" if (DEBUG);
$objectTemplates{$objectTemplate}->[1] = NOT_COLLIDEABLE;
next;
}
my $collideable = UNTESTED;
my $analyzingObjectTemplate = $objectTemplate;
my $debugTabs = "";
while ($collideable == UNTESTED)
{
my $forceNoCollision = 0;
my $appearanceTemplate = "";
my $baseObjectTemplate = "";
my $sharedObjectTemplate = "";
my $portalLayoutFile = "";
if (DEBUG)
{
print "${debugTabs}Scanning $analyzingObjectTemplate...\n";
$debugTabs .= "\t";
}
my $analyzingObjectTemplateDisk = $objectTemplates{$analyzingObjectTemplate}->[0];
open (OT, $analyzingObjectTemplateDisk) || die "Can't open $analyzingObjectTemplateDisk\n";
while (<OT>)
{
$baseObjectTemplate = $1 if (m/^\s*\@base\s+(\S+)/i);
$forceNoCollision = 1 if (m/^\s*forceNoCollision\s*=\s*true/i);
$appearanceTemplate = $1 if (m/^\s*appearanceFilename\s*=\s*\"(\S+)\"/i);
$sharedObjectTemplate = $1 if (m/^\s*(?:crafted)?sharedTemplate\s*=\s*\"(\S+)\"/i);
$portalLayoutFile = $1 if (m/^\s*portalLayoutFilename\s*=\s*\"(\S+)\"/i);
}
close (OT);
if ($forceNoCollision)
{
print "$objectTemplate : not collideable : forceNoCollision specified\n" if (DEBUG);
$collideable = NOT_COLLIDEABLE;
last;
}
if ($portalLayoutFile)
{
print "$objectTemplate : collideable : portal layout found\n" if (DEBUG);
$collideable = COLLIDEABLE;
last;
}
if ($appearanceTemplate)
{
my $appearanceTemplateDisk = (exists $appearanceTemplates{$appearanceTemplate}) ? $appearanceTemplates{$appearanceTemplate}->[0] : "";
if ($appearanceTemplateDisk =~ m!/sys\.client/!)
{
print "$objectTemplate : not collideable : appearance is client side only\n" if (DEBUG);
$collideable = NOT_COLLIDEABLE;
last;
}
else
{
print "${debugTabs}Scanning appearance $appearanceTemplate...\n" if (DEBUG);
if ($appearanceTemplateDisk)
{
my $appearanceFileHandle;
open ($appearanceFileHandle, $appearanceTemplateDisk) || die "Can't open $appearanceTemplateDisk\n";
my $iff = Iff->createFromFileHandle($appearanceFileHandle);
close ($appearanceFileHandle);
# Handle Iff contents.
my $name = $iff->getCurrentName();
if ($name eq "APT " && $iff->isCurrentForm())
{
$iff->enterForm();
$name = $iff->getCurrentName();
if ($name eq "0000" && $iff->isCurrentForm())
{
$iff->enterForm();
$name = $iff->getCurrentName();
if ($name eq "NAME" && !$iff->isCurrentForm())
{
$iff->enterChunk();
my $ssaFileName = $iff->read_string();
print "${debugTabs}Scanning ssa $ssaFileName...\n" if (DEBUG);
my $ssaFileNameDisk = (exists $appearanceTemplates{$ssaFileName}) ? $appearanceTemplates{$ssaFileName}->[0] : "";
if ($ssaFileNameDisk)
{
my $ssaFileHandle;
open ($ssaFileHandle, $ssaFileNameDisk) || die "Can't open $ssaFileNameDisk\n";
$iff = Iff->createFromFileHandle($ssaFileHandle);
close ($ssaFileHandle);
# Handle Iff contents
my $name = $iff->getCurrentName();
if ($name eq "APPR" && $iff->isCurrentForm())
{
$iff->enterForm();
$name = $iff->getCurrentName();
if ($name eq "0003" && $iff->isCurrentForm())
{
$iff->enterForm();
# enter / exit past extent block
$iff->enterForm();
$iff->exitForm();
# we should now be pointing to the collision property form
$name = $iff->getCurrentName();
if ($name eq "NULL")
{
# enter / exit past collision property block
$iff->enterForm();
$iff->exitForm();
# enter / exit past hardpoint block
$iff->enterForm();
$iff->exitForm();
$name = $iff->getCurrentName();
if ($name eq "FLOR" && $iff->isCurrentForm())
{
$iff->enterForm();
$name = $iff->getCurrentName();
if ($name eq "DATA" && !$iff->isCurrentForm())
{
$iff->enterChunk();
my $hasFloor = $iff->read_uint8();
if ($hasFloor == 0)
{
print "$objectTemplate : not collideable : null collision property and null floor\n" if (DEBUG);
$collideable = NOT_COLLIDEABLE;
}
else
{
print "$objectTemplate : collideable : non-null floor\n" if (DEBUG);
$collideable = COLLIDEABLE;
}
}
}
}
else
{
print "$objectTemplate : collideable : non-null collision property\n" if (DEBUG);
$collideable = COLLIDEABLE;
}
}
else
{
# for all other forms of this piece of data, we assume not collideable
print "$objectTemplate : not collideable : null collision property\n" if (DEBUG);
$collideable = NOT_COLLIDEABLE;
}
}
}
}
}
}
# if we got here and didn't get a solution, default to collideable
if ($collideable == UNTESTED)
{
print "$objectTemplate : collideable : couldn't get appearance template info\n" if (DEBUG);
$collideable = COLLIDEABLE;
last;
}
}
}
}
$sharedObjectTemplate =~ s!\.iff!\.tpf!;
$baseObjectTemplate =~ s!\.iff!\.tpf!;
if (!$sharedObjectTemplate || !exists $objectTemplates{$sharedObjectTemplate})
{
if (!$baseObjectTemplate || !exists $objectTemplates{$baseObjectTemplate})
{
print "$objectTemplate : collideable : no base, no shared, no appearance specified, defaulting\n" if (DEBUG);
$collideable = COLLIDEABLE;
last;
}
else
{
$sharedObjectTemplate = "";
}
}
$analyzingObjectTemplate = ($sharedObjectTemplate) ? $sharedObjectTemplate : $baseObjectTemplate;
}
$objectTemplates{$objectTemplate}->[1] = $collideable;
}
print "\nPrinting out object templates with collision...\n";
foreach my $template (sort keys %objectTemplates)
{
print "$template\n" if ($objectTemplates{$template}->[1] == COLLIDEABLE && $template !~ /shared_/);
}

View File

@@ -0,0 +1,90 @@
#!/bin/perl
use strict;
# Call with the following args:
# -n <newVariableNameFile> -a <assetInfoFile>
my $newVariableFileName;
my $assetInfoFileName;
my $debug = 0;
my %targetVariableNames;
sub loadTargetVariableNamesFromFile
{
my $filename = shift;
my $fileHandle;
open($fileHandle, "<$filename") or die "failed to open file [$filename]: $!";
while (<$fileHandle>)
{
chomp;
if ($_ =~ m/\[(.+)\]/)
{
my $name = $1;
$targetVariableNames{$name} = 1;
print STDERR "target variable [$name]\n" if $debug;
}
}
close($fileHandle);
}
sub findVariableNameUsage
{
my $filename = shift;
my $fileHandle;
print "variableName\treferencing assetName\n";
open($fileHandle, "<$filename") or die "failed to open file [$filename]: $!";
while (<$fileHandle>)
{
chomp;
if (($_ =~ m/^I /) || ($_ =~ m/^P /))
{
# kill code letters.
s/..//;
# read asset name and variable name.
m/([^:]+):([^:]+):/ or die "line [$_] does not match customization variable info data format";
my $assetName = $1;
my $variableName = $2;
# if the variable name is one of the targets, print out the asset.
if (exists $targetVariableNames{$variableName})
{
print "$variableName\t$assetName\n";
}
}
}
close($fileHandle);
}
# Process args
while (@ARGV)
{
my $currentArg = shift @ARGV;
if ($currentArg =~ m/-d/)
{
$debug = 1;
print STDERR "debugging turned on\n";
}
elsif ($currentArg =~ m/-n/)
{
$newVariableFileName = shift @ARGV;
print STDERR "newVariableFileName=[$newVariableFileName]\n" if $debug;
}
elsif ($currentArg =~ m/-a/)
{
$assetInfoFileName = shift @ARGV;
print STDERR "assetInfoFileName=[$assetInfoFileName]\n" if $debug;
}
}
# Load in new variable names
loadTargetVariableNamesFromFile($newVariableFileName);
# Find asset usage of target names
findVariableNameUsage($assetInfoFileName);

View File

@@ -0,0 +1,159 @@
#!/bin/perl
use strict;
use Iff;
my %filenamesToProcess;
my $debug = 0;
my %skeletonNames;
sub collectFileNamesToProcess
{
foreach my $filenameGlob (@_)
{
my @filenames = glob($filenameGlob);
foreach my $filename (@filenames)
{
$filenamesToProcess{$filename} = 1;
}
}
}
sub printFileNames
{
print "Filenames:\n";
my @sortedFileNames = sort {$a cmp $b} keys %filenamesToProcess;
foreach my $filename (@sortedFileNames)
{
print "$filename\n";
}
print "Total: ", scalar(@sortedFileNames), " files\n";
}
sub iffCallbackCollectSkeletons
{
my $iff = shift;
my $blockname = shift;
my $isChunk = shift;
if ($isChunk && ($blockname eq "SKTI"))
{
while ($iff->getChunkLengthLeft() > 0)
{
my $skeletonTemplateName = $iff->read_string();
my $attachmentTransformName = $iff->read_string();
# @todo: catch multiple counts of the same skeleton template name.
$skeletonNames{$skeletonTemplateName} = 1;
}
}
return 1;
}
sub processSatIff
{
# Setup args.
my $satFileName = shift;
my $iff = shift;
# Collect skeleton templates referenced by this iff.
%skeletonNames = ();
$iff->walkIff(\&iffCallbackCollectSkeletons);
# Process skeleton template names.
my $faceSkeletonCount = 0;
foreach my $skeletonTemplateName (sort {$a cmp $b} keys %skeletonNames)
{
my $workingSkeletonName = $skeletonTemplateName;
# Strip off directories in the skeleton template name.
$workingSkeletonName =~ s!\\!/!;
$workingSkeletonName =~ s!^.+/!!;
# Strip off .skt part.
$workingSkeletonName =~ s!.skt$!!;
print "workingSkeletonName=[$workingSkeletonName]\n" if $debug;
if ($workingSkeletonName eq "all_b")
{
#ignore all_b skeleton.
}
elsif ($workingSkeletonName =~ m/([^_]+)_([^_]+)_face/)
{
++$faceSkeletonCount;
my $speciesAbbrev = $1;
my $genderAbbrev = $2;
my $invalidSatName = 0;
my $shouldContainForSpecies = '(^|_)' . $speciesAbbrev . '_';
if (!($satFileName =~ m/$shouldContainForSpecies/))
{
++$invalidSatName;
}
my $satShouldContainForGender = '_' . $genderAbbrev . '(_|.sat)';
if (!($satFileName =~ m/$satShouldContainForGender/))
{
++$invalidSatName;
}
if ($invalidSatName > 0)
{
# The SAT file references species/gender specific skeleton template but the SAT filename doesn't indicate the species/gender dependency.\n";
print "$satFileName\t$skeletonTemplateName\tspecies/gender skeleton referenced, invalid SAT name.\n";
}
}
else
{
# Try matching the whole working skeleton name within the sat, indicating that the skeleton and sat are joined.
my $validSatNamePattern = '(^|_)' . $workingSkeletonName . '(_|.sat)';
if (!($satFileName =~ m/$validSatNamePattern/))
{
print "$satFileName\t$skeletonTemplateName\tunexpected skeleton template name\n";
}
}
}
print "$satFileName\t****\treferenced $faceSkeletonCount face skeletons\n" if $faceSkeletonCount > 1;
}
sub processFiles
{
foreach my $filename (@_)
{
# Open the file, create an Iff instance from it.
my $fileHandle;
open($fileHandle, "<$filename") or die "cannot open file [$filename]: $!";
my $iff = Iff->createFromFileHandle($fileHandle);
close($fileHandle);
# Handle Iff contents.
my $initialName = $iff->getCurrentName();
if (($initialName ne "SMAT") || !$iff->isCurrentForm())
{
print "$filename: not a .SAT file, ignoring\n";
}
else
{
$iff->enterForm();
processSatIff($filename, $iff);
$iff->exitForm();
}
}
}
# Print usage.
die "Usage: perl findBadSkeletonBindings.pl <.sat fileglob> [ <.sat fileglob> [...]]\n" if (@ARGV == 0);
# Collect files to process.
collectFileNamesToProcess(@ARGV);
printFileNames() if $debug;
processFiles(sort {$a cmp $b} keys %filenamesToProcess);

View File

@@ -0,0 +1,40 @@
$dir = shift @ARGV;
$lookIn = shift @ARGV;
$lookFor = shift @ARGV;
die "usage: directory extension_to_look_within extension_to_look_for\n" if (!defined($lookFor));
sub dodir
{
local($dir) = @_;
opendir(DIR, $dir) || die "opendir failed";
local(@dir) = readdir(DIR);
closedir(DIR);
foreach (@dir)
{
next if ($_ eq '.');
next if ($_ eq '..');
local($path) = $dir . '/' . $_;
if (-d $path)
{
&dodir($path);
}
else
{
push(@files, $path) if (/\.$lookIn$/)
}
}
}
&dodir($dir);
foreach $file (sort @files)
{
open(STRINGS, 'strings ' . $file . ' |');
while (<STRINGS>)
{
chomp;
print $file . "\t" . $_ . "\n" if (/\.$lookFor$/);
}
}

View File

@@ -0,0 +1,40 @@
$dir = shift @ARGV;
$lookIn = shift @ARGV;
$lookFor = shift @ARGV;
die "usage: directory extension_to_look_within tag_to_look_for_backwards\n" if (!defined($lookFor));
sub dodir
{
local($dir) = @_;
opendir(DIR, $dir) || die "opendir failed";
local(@dir) = readdir(DIR);
closedir(DIR);
foreach (@dir)
{
next if ($_ eq '.');
next if ($_ eq '..');
local($path) = $dir . '/' . $_;
if (-d $path)
{
&dodir($path);
}
else
{
push(@files, $path) if (/\.$lookIn$/)
}
}
}
&dodir($dir);
foreach $file (sort @files)
{
open(STRINGS, 'strings ' . $file . ' |');
while (<STRINGS>)
{
chomp;
print $file . "\t" . $_ . "\n" if (/$lookFor$/);
}
}

View File

@@ -0,0 +1,83 @@
#!/usr/bin/perl
use File::Find;
# process command line arguments
while ($ARGV[0] =~ /^-/)
{
$_ = shift;
if ($_ eq "--debug")
{
$debug = 1;
}
elsif ($_ eq "--delete")
{
$delete = 1;
}
else
{
die "unknown command line option";
}
}
sub CollectP4OpenedFiles
{
open(P4, "p4 opened |");
while (<P4>)
{
chomp;
$openedFiles{$_} = 1 if (s/#.*//);
}
close(P4);
}
sub FindHandler
{
if (-d $_)
{
# found a directory entry
# prune the directory if it's one we want to ignore
if (m/^(compile|external|Debug|Optimized|Production|Release|generated)$/)
{
# prune it
$File::Find::prune = 1;
print STDERR "[Pruned Directory Entry: $File::Find::name]\n" if ($debug);
}
}
elsif (-f and -w $_)
{
# handle writable non-directory entry
if (!m/^.*(\.(aps|ca|clw|class|dll|ews|exe|ncb|opt|plg|WW|tmp|db|bak|pyc|cfg|o)|~)$/)
{
# this is a writable file that should be checked against what's in Perforce.
my ($commandLine, $expectedDepotLocation);
$commandLine = `p4 where $File::Find::name`;
$commandLine =~ /([^ ]+) /;
$expectedDepotLocation = $1;
# this writable file is suspect (i.e. is missing) if the depot file
# is not opened. That implies the file is writable but not opened,
# most likely indicating it doesn't exist in the depot.
if (!$openedFiles{$expectedDepotLocation})
{
print $File::Find::name, "\n";
unlink $File::Find::name if ($delete);
}
else
{
print STDERR "<file [$File::Find::name] is in perforce>\n" if ($debug);
}
}
}
}
# collect opened depot files
CollectP4OpenedFiles();
# do a find
@ARGV = ('../') unless @ARGV;
find(\&FindHandler, @ARGV);

View File

@@ -0,0 +1,42 @@
#!/usr/bin/perl
open(IN, "swg.dsw") || die "could not open swg.dsw\n";
open(OUT, ">swg.new");
$project = "";
while (<IN>)
{
print OUT;
chomp;
if (s/^Project: "//)
{
s/".*//;
$project = $_;
}
if (/^Package=<5>/ && $project ne "")
{
while ($_ ne "}}}\n")
{
$_ = <IN>;
}
print OUT "{{{\n";
print OUT " begin source code control\n";
print OUT " $project\n";
print OUT " .\n";
print OUT " end source code control\n";
print OUT "}}}\n";
$project = "";
}
}
close(IN);
close(OUT);
unlink("swg.dsw");
rename("swg.new", "swg.dsw");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
my @exceptions;
my $currentException = 0;
my $nearestWarning = "";
while(<STDIN>)
{
if($_ =~ /^* : WARNING |^WARNING: /)
{
$nearestWarning = $_;
}
if ($_ =~ /^java/)
{
$currentException++;
$exceptions[$currentException] = $nearestWarning.$_;
}
elsif($_ =~ /\s+at /)
{
$exceptions[$currentException] .= $_;
}
}
my @reportOutput;
my $reportIndex = 0;
my %dupeReport;
for ($i = 0; $i < @exceptions; $i++)
{
$duped = 0;
for($j = 0; $j < @reportOutput; $j++)
{
if($exceptions[$i] eq $reportOutput[$j])
{
$duped = 1;
break;
}
}
$reports = 1;
for($j = 0; $j < @exceptions; $j++)
{
if($i != $j)
{
if($exceptions[$i] eq $exceptions[$j])
{
$reports++;
}
}
}
if($duped == 0)
{
$callStack = $exceptions[$i];
$reportOutput[$reportIndex] = $exceptions[$i];
$reportIndex++;
$dupeReport{$callStack} = $reports;
}
}
print "Java Exception Report: $reportIndex unique call stacks logged. Total call stacks: $currentException\n";
print "Detailed report follows.\n\n\n\n";
foreach my $key (sort{$dupeReport{$b} <=> $dupeReport{$a}} keys %dupeReport)
{
print "\n=============================================\n\n";
print "$dupeReport{$key} reports:\n";
print $key;
}

View File

@@ -0,0 +1,16 @@
while (<>)
{
chomp;
s/\d+\s+\d+\.\d+\s+\[\d+\]\s+//;
s/\s+$//;
$file = $_ if ($opening);
$opening = /^opening/;
if (defined($file) && /WARNING/)
{
print $file, "\n" if ($printed ne $file);
$printed = $file;
print "\t", $_, "\n"
}
}

View File

@@ -0,0 +1,126 @@
#!/usr/perl/bin
sub usage
{
die "usage: perl gatherWarnings.pl [-c] [-s ##] [-dv] [-nl] sourceFile ...\n" .
"\t-c = count repeated warnings\n" .
"\t-s = combine similar warnings that differ by no more than ## words (implies -c)\n" .
"\t-dv = strip debug view timestamps\n" .
"\t-nl = strip warning locations\n";
}
while ($ARGV[0] =~ /^-/ && $ARGV[0] ne "-")
{
if ($ARGV[0] eq "-dv")
{
$debugView = 1;
}
elsif ($ARGV[0] eq "-nl")
{
$noLocation = 1;
}
elsif ($ARGV[0] eq "-s")
{
$similar = $ARGV[1];
$count = 1;
shift;
}
elsif ($ARGV[0] eq "-c")
{
$count = 1;
}
else
{
usage();
}
shift @ARGV;
}
usage if (@ARGV == 0);
sub numerically
{
return -($a <=> $b);
}
while (<>)
{
s/^\s*\d+\s+\d+\.\d+\s+\[\d+\]\s+// if ($debugView);
s/\S+ : WARNING:/WARNING:/ if ($noLocation);
s/\s+/ /;
if (/WARNING:/)
{
if ($similar)
{
chomp;
foreach $compare (keys %warnings)
{
@current = split(/\s+/, $_);
@compare = split(/\s+/, $compare);
if (scalar(@current) == scalar(@compare))
{
$count = 0;
$out = "";
while (@current)
{
$a = shift @current;
$b = shift @compare;
if ($a eq $b)
{
$out .= " $a";
}
else
{
$out .= " XXXX";
$count += 1;
}
}
if ($count <= $similar)
{
$out =~ s/^ //;
if ($warnings{$out} ne $warnings{$compare})
{
$warnings{$out} = $warnings{$compare};
delete $warnings{$compare};
}
$_ = $out;
}
else
{
}
}
}
$warnings{$_} += 1 if ($repeat == 0)
}
elsif ($count)
{
chomp;
$warnings{$_} += 1;
}
else
{
print;
}
}
}
if ($count)
{
foreach (keys %warnings)
{
push(@warnings, sprintf("%5d %s", $warnings{$_}, $_));
}
foreach (sort numerically @warnings)
{
print $_, "\n";
}
}

View File

@@ -0,0 +1,58 @@
# Syntax: perl getFileSizeInDirectoryTree.pl [-d] [directory [pathname_regex]]
use strict;
use File::Find;
my $debug = 0;
my $pathnameMustMatchRegex;
# Subroutine called by File::Find.
sub processFile
{
print STDERR "testing [$File::Find::name]..." if $debug;
if (!defined($pathnameMustMatchRegex) || $File::Find::name =~ m/$pathnameMustMatchRegex/)
{
print STDERR "matched, printing.\n" if $debug;
my @fileStat = stat;
my $formattedName = $File::Find::name;
$formattedName =~ s!\\!/!g;
print "$fileStat[7] $formattedName\n";
}
else
{
print STDERR "no match, skipping.\n" if $debug;
}
}
# Check for help.
if (defined($ARGV[0]) && $ARGV[0] =~ m/-h/)
{
print "Syntax: getFileSizeInDirectoryTree.pl [directory [pathname_regex]]\n";
print "\tpathname_regex is a Perl-compatible regular expression, matches all if not specified.\n";
exit 0;
}
# Check for debug.
if (defined($ARGV[0]) && $ARGV[0] =~ m/-d/)
{
$debug = 1;
print STDERR "\$debug = 1\n";
shift @ARGV;
}
# Setup directory.
my @directories = ($ARGV[0]);
$directories[0] = '.' if !defined($directories[0]);
print STDERR "directories = [@directories]\n" if $debug;
# Setup regex.
$pathnameMustMatchRegex = $ARGV[1] if defined($ARGV[1]);
$pathnameMustMatchRegex =~ s/[\'\"]//g if defined($pathnameMustMatchRegex);
print STDERR "pathnameMustMatchRegex = [$pathnameMustMatchRegex]\n" if ($debug && defined($pathnameMustMatchRegex));
# Do the find.
File::Find::find(\&processFile, @directories);
# Done.

View File

@@ -0,0 +1,127 @@
# process all the files on the command line
while ($_ = shift(ARGV))
{
# handle RSP files by reading their content and putting that back on the command line
if (/.rsp/ || /.RSP/)
{
open(RSP, $_);
while (<RSP>)
{
chop;
push(add, $_)
}
unshift(ARGV, @add);
undef @add;
close(RSP);
next;
}
# provide status
print $_ . ":\n";
if (/.CPP/ || /.cpp/)
{
print " skipping source file\n";
next;
}
# open the files for i/o
$file = $_;
$new = $file . ".new";
open(IN, $file);
# process all the lines in the input file
undef %symbol;
undef %required;
undef %inline;
while (<IN>)
{
chop;
# strip comments
s#//.*##;
if (/#include\s+"/)
{
($junk1, $header, $junk2) = split(/[" ]+/);
$class = $header;
$class =~ s#.*/##;
$class =~ s#\.h##;
if (!($class =~ /^First/))
{
$symbol{$class} = $header;
$required{$class} = "_";
$inline{$class} = "_";
}
}
elsif (/#include\s+</)
{
print " " . $_ . "\n";
}
else
{
if (/^\s*inline/)
{
$section = "inline";
}
elsif (/^\s*class/)
{
$section = "class";
}
foreach $class (keys %symbol)
{
if ($section eq "class")
{
# handle derived from
$required{$class} = "R" if (/:\s*public\s+$class/);
# handle use of nested class
$required{$class} = "R" if (/$class\s*::/);
# handle member variable
$required{$class} = "R" if (/^\s*$class\s+[a-zA-Z_]\w*\s*;\s*$/);
# handle member variable
$required{$class} = "R" if (/^\s*$class\s+[a-zA-Z_]\w*\s*;\s*$/);
# handle mutable member variable
$required{$class} = "R" if (/^\s*mutable\s+$class\s+[a-zA-Z_]\w*\s*;\s*$/);
# handle const member variable
$required{$class} = "R" if (/^\s*const\s+$class\s+[a-zA-Z_]\w*\s*;\s*$/);
}
elsif ($section eq "inline")
{
# handle use of nested class
$inline{$class} = "I" if (/$class\s*::/);
# handle inline function argument
$inline{$class} = "I" if (/^\binline\b.*\b$class\b/);
# handle local variable
$inline{$class} = "I" if (/^\s*$class\s+[a-zA-Z_]\w*\s*;\s*$/);
# handle const local variable
$inline{$class} = "I" if (/^\s*const\s+$class\s+[a-zA-Z_]\w*\s*;\s*$/);
}
}
}
}
# done accessing the contents of the files
close(IN);
foreach $b (sort keys %symbol)
{
print " " . $required{$b} . $inline{$b} ." " . $b . " = " . $symbol{$b} . "\n";
}
}

120
gameserver/utils/tools/inctree.pl Executable file
View File

@@ -0,0 +1,120 @@
#!/usr/bin/perl
# Usage: inctree [options] [files]
# Configuration parameters.
$CPP = 'gcc -E';
# $CPP = "cc -P";
# $CPP = "/lib/cpp";
$shiftwidth = 4;
# Process switches.
while ($ARGV[0] =~ /^-/) {
$_ = shift;
if (/^-D(.*)/) {
$defines .= " -D" . ($1 ? $1 : shift);
}
elsif (/^-BW/) {
$CPP = 'cl /nologo /E';
$count = 0;
while (! chdir "build/win32")
{
die "could not find build/win32 in search backwards" if (++$count > 50);
chdir "..";
}
}
elsif (/^-I(.*)/) {
$include = ($1 ? $1 : shift);
if ($include =~ /\.rsp$/)
{
open(RSP, $include);
while (<RSP>)
{
chop;
$includes .= " -I" . $_;
}
close(RSP);
}
else {
$includes .= " -I" . $include;
}
}
elsif (/^-m(.*)/) {
push(@pats, $1 ? $1 : shift);
}
elsif (/^-l/) {
$lines++;
}
else {
die "Unrecognized switch: $_\n";
}
}
# Build a subroutine to scan for any specified patterns.
if (@pats) {
$sub = "sub pats {\n";
foreach $pat (@pats) {
$sub .= " print '>>>>>>> ',\$_ if m$pat;\n";
}
$sub .= "}\n";
eval $sub;
++$pats;
}
# Now process each file on the command line.
foreach $file (@ARGV) {
open(CPP,"$CPP $defines $includes $file|")
|| die "Can't run cpp: $!\n";
$line = 2;
while (<CPP>) {
++$line;
&pats if $pats; # Avoid expensive call if we can.
s/^#line /# /; # handle dev-studio style line info as well
next unless /^#/;
next unless /^# \d/;
chop;
s/\\+/\\/g;
s/\\/\//g;
while (s#/\w+/../#/#) {}
($junk,$newline,$filename) = split(/\s+/, $_, 3);
$filename =~ s/"//g;
$filename =~ s/^\s+//;
$filename =~ s/\s+$//;
# Now figure out if it's a push, a pop, or neither.
if ($stack[$#stack] eq $filename) { # Same file.
$line = $newline-1;
next;
}
if ($stack[$#stack-1] eq $filename) { # Leaving file.
$indent -= $shiftwidth;
$line = pop(@lines)-1;
pop(@stack);
}
else { # New file.
printf "%6d ", $line-2 if $lines;
push(@lines,$line);
$line = $newline;
print " " x ($indent), $filename;
print " DUPLICATE" if $seen{$filename}++;
print "\n";
$indent += $shiftwidth;
push(@stack,$filename);
}
}
close CPP;
$indent = 0;
%seen = ();
print "\n\n";
$line = 0;
}

View File

@@ -0,0 +1,31 @@
#! /usr/bin/perl
use strict;
use warnings;
my $minimumTime = 0.0;
if (@ARGV >= 2 && $ARGV[0] eq "-m")
{
shift;
$minimumTime = shift;
}
die "usage: $0 [-m time] logfile\n\t-m = minimum time (in seconds) to report\n" if (@ARGV != 1 || $ARGV[0] =~ /^[-\?\/]/);
my @reverse;
while (<>)
{
next if (s/InstallTimer: // == 0);
push(@reverse, $_);
}
while (@reverse)
{
$_ = pop(@reverse);
my $line = $_;
chomp;
s/^\s+//;
my ($time, $whom) = split(/\s+/, $_);
print $line if ($time >= $minimumTime);
}

View File

@@ -0,0 +1,7 @@
#!/bin/sh -f
while [ $# -gt 0 ]; do
cat ../src/engine/shared/library/sharedFoundation/src/shared/GameControllerMessage.def |grep CM_ |grep -v CM_nothing |nl |grep "^[^0-9]*$1[^0-9]"
shift 1
done

View File

@@ -0,0 +1,177 @@
#!/usr/bin/perl
use strict;
use warnings;
die "usage: perl makeAsynchronousLoadData sourceFile.log outputFile.mif oldFileList.txt\n" if (@ARGV != 3);
# global variables
my @children = ();
my @files = ();
my $counter = 0;
my %files;
my %fileExtensionIndex;
my %extensionOffset;
my %extensionIndex;
my %children;
# command line arguments
my $inFile = shift;
my $outFile = shift;
my $fileList = shift;
sub numerically
{
return $a <=> $b;
}
sub extensionOffset_numerically
{
return $extensionOffset{$a} <=> $extensionOffset{$b};
}
sub next_parent
{
if (@children)
{
my $count = @children;
my $parent = shift(@children);
$children{$parent} = join("\n int32 ", "", $count, $parent, @children) . "\n";
@children = ();
}
}
# process the old file table to minimize differential patching
open(FILES, $fileList) || die "could not open file $fileList for reading\n";
while (<FILES>)
{
chomp();
$files{$_} = $counter;
$counter += 2 + length($_) + 1;
push(@files, $_);
# now check the extension
my $extension = $_;
$extension =~ s/^.*\.//;
my $extensionIndex = $extensionIndex{$extension};
if (!defined($extensionIndex{$extension}))
{
$extensionIndex{$extension} = scalar keys %extensionOffset;
$extensionOffset{$extension} = $counter - length($extension) - 1;
$extensionIndex = $extensionIndex{$extension};
}
$fileExtensionIndex{$_} = $extensionIndex;
}
close(FILES);
open(FILES, $inFile) || die "could not open file $inFile for reading\n";
{
my $opening = 0;
while (<FILES>)
{
# 20030711155304:Viewer:reportLog:TF::open(M) d:/work/swg/test/data/sku.0/sys.client/built/game/appearance/path_arrow.msh @ d:/work/swg/test/data/sku.0/sys.client/built/game/appearance/path_arrow.msh, [size=2109]
s/\d+\:Viewer\:reportLog\://;
# check if this is an opening line, which separates primary assets
if (/^opening/)
{
next_parent() if ($opening);
$opening = 1;
}
next if (!$opening);
next if (!/TF::open/);
chomp;
# clean up the file name
s/^.*TF::open\([A-Z]\) //;
s/ @.*//;
s#\\#/#g;
s#//#/#g;
tr/A-Z/a-z/;
s#^.*/appearance/#appearance/#;
# check for it in the file list
my $index = $files{$_};
if (!defined($index))
{
$files{$_} = $counter;
$index = $counter;
$counter += 2 + length($_) + 1;
push(@files, $_);
}
push(@children, $index) if (scalar(grep(/^$index$/, @children)) == 0);
# now if the extension is known
my $extension = $_;
$extension =~ s/^.*\.//;
my $extensionIndex = $extensionIndex{$extension};
if (!defined($extensionIndex))
{
$extensionIndex{$extension} = scalar keys %extensionOffset;
$extensionOffset{$extension} = $counter - length($extension) - 1;
$extensionIndex = $extensionIndex{$extension};
}
# remember the extension table index for this file
$fileExtensionIndex{$_} = $extensionIndex;
}
# finish the last primary asset
next_parent();
}
close(FILES);
# write out the new file table to minimize the diff the next time the async data is updated
open(FILES, ">" . $fileList) || die "could not open file $fileList for writing\n";
foreach (@files)
{
print FILES $_, "\n";
}
close(FILES);
# write out the mif data
open(OUTPUT, ">$outFile");
select(OUTPUT);
print "form \"ASYN\"\n";
print "{\n";
print " form \"0001\"\n";
print " {\n";
print " chunk \"NAME\"\n";
print " {\n";
foreach (@files)
{
print " int8 0\n";
die "no extension for $_\n" if (!defined($fileExtensionIndex{$_}));
print " int8 $fileExtensionIndex{$_}\n";
print " cstring \"$_\"\n";
}
print " }\n";
print " chunk \"EXTN\"\n";
print " {\n";
foreach (sort extensionOffset_numerically keys %extensionOffset)
{
print " int32 $extensionOffset{$_} // $_\n";
}
print " }\n";
print " chunk \"LOAD\"\n";
print " {\n";
foreach (sort numerically keys %children)
{
print $children{$_};
}
print " }\n";
print " }\n";
print "}\n";
select;
close(OUTPUT);

View File

@@ -0,0 +1,127 @@
# Script to take output from the Transform::multiply tracking REPORT_LOG output
# and generate a report of callstacks sorted in descending frequency order.
use strict;
my $inCallstack = 0;
my $callstackFrequency = 0;
my $callstackLinesRef;
my $debug = 0;
my %callstacksByFrequency;
sub submitCallstack
{
die "bad callstackFrequency [$callstackFrequency]" if (!($callstackFrequency =~ m/^\d+$/));
return if (@$callstackLinesRef < 1);
# Make sure there's an array reference to hold all callstacks mapping to this frequency.
if (!exists $callstacksByFrequency{$callstackFrequency})
{
$callstacksByFrequency{$callstackFrequency} = [];
}
# Get array ref.
my $callstackArrayRef = $callstacksByFrequency{$callstackFrequency};
# Add callstack lines array to it.
push @$callstackArrayRef, $callstackLinesRef;
}
sub resetCallstack
{
$callstackLinesRef = [];
}
while (<>)
{
#-- Clean up line: remove line number and time info from log.
chomp();
s/\d+\s+\d+\.\d+\s+//;
#-- Process line.
# Check if this matches a start of callstack line.
if (m/Transform::multiply/)
{
if ($inCallstack)
{
# Add existing (now complete) callstack, restart a new one immediately following, starting on this line.
submitCallstack();
}
else
{
# Mark that we're now in a callstack so we know to scan following lines.
$inCallstack = 1;
}
resetCallstack();
# Parse out frequency.
if (m/called (\d+) times/)
{
$callstackFrequency = $1;
}
else
{
die "Failed to get call frequency on input line [$_]";
}
# Remove unique callstack numeric info at end since we sort differently (by frequency) than raw output.
s/\s\(\d+ of \d+ unique callstacks\)//;
# Add header line to callstack lines.
push @$callstackLinesRef, $_;
print "Found callstack frequency [$callstackFrequency]\n" if $debug;
}
elsif ($inCallstack)
{
# Fixiup lines I bumbled output on.
s/(\d+) caller \d+/caller $1/;
if (m/caller \d+/)
{
if (!m/unknown/)
{
# Looks like a good callstack line, keep it.
push @$callstackLinesRef, $_;
}
}
else
{
# Looks like this callstack is done.
submitCallstack();
$inCallstack = 0;
}
}
}
# Print out callstacks sorted by descending numeric frequency.
my @frequencies = sort { return $b <=> $a; } (keys %callstacksByFrequency);
print "There are ", @frequencies + 0, " unique callstack frequencies.\n";
foreach my $frequency (@frequencies)
{
my $callstackArrayRef = $callstacksByFrequency{$frequency};
my $callstackCount = @$callstackArrayRef;
print "========================================\n";
print "FREQUENCY: $frequency ($callstackCount callstacks)\n";
print "========================================\n";
print "\n";
for (my $i = 0; $i < $callstackCount; ++$i)
{
my $callstackLinesRef = $$callstackArrayRef[$i];
my $lineCount = @$callstackLinesRef;
print "$$callstackLinesRef[0]\n";
for (my $lineIndex = 1; $lineIndex < $lineCount; ++$lineIndex)
{
print "\t$$callstackLinesRef[$lineIndex]\n";
}
print "\n";
}
}
print "DONE.\n";

View File

@@ -0,0 +1,64 @@
die "usage: mapFileLookUpWin32.pl file.map [[address | \@responseFile]...]\n" if (@ARGV < 2);
$mapFile = shift(@ARGV);
open(MAP, $mapFile);
while (@ARGV)
{
$find = shift(@ARGV);
# handle response files that are call stacks
if ($find =~ /^\@/)
{
$find =~ s/^.//;
# search the file for IP addresses to look up
undef @find;
open(FIND, $find);
while (<FIND>)
{
chomp;
s/^.*unknown\(// && s/\).*//;
push(@find, $_) if ($_ ne "");
}
close(FIND);
# insert all the found entries at the beginning of @ARGV
splice(@ARGV, 0, 0, @find);
$find = shift(@ARGV);
}
$find = hex($find);
# go to the beginning and skip past some cruft
seek(MAP, 0, 0);
while (<MAP>)
{
last if (/^\s+Address/)
}
# search for the symbol containg this address
$found = 0;
$lastAddress = 0;
$lastSymbol = "";
while (<MAP>)
{
chomp;
($seg, $symbol, $address, $junk) = split;
$address = hex($address);
if ($lastAddress <= $find && $address > $find)
{
printf "%08x: %08x %08x %s\n", $find, $lastAddress, $address, $lastSymbol;
$found = 1;
last;
}
$lastAddress = $address;
$lastSymbol = $symbol;
}
printf "%08x: not found\n", $find if ($found == 0);
}
close(MAP);

View File

@@ -0,0 +1,74 @@
die "usage: perl memoryReport.pl [-c (sort by count) | -a (sort by allocated amount)] [-l] logFile.txt" if (@ARGV < 1 || $ARGV[0] eq "-h");
$sortMethod = 0; # 0 = using sort by allocated amount, 1 = sort by allocation count
if ($ARGV[0] eq "-c")
{
shift @ARGV;
$sortMethod = 1;
}
if ($ARGV[0] eq "-a")
{
shift @ARGV;
$sortMethod = 0;
}
if ($ARGV[0] eq "-l")
{
shift @ARGV;
$lines = 1;
}
sub sortAllocated
{
return -($allocated{$a} <=> $allocated{$b});
}
sub sortCount
{
return -($count{$a} <=> $count{$b});
}
while (<>)
{
chomp;
if (/memory allocation/ || /memory leak/)
{
s/.*[\/\\]//;
s/^.*unknown/unknown/;
s/:.*,//;
s/bytes$//;
s/\(.*\)// if (! $lines);
($file, $size) = split;
$allocated{$file} += $size;
$count{$file} += 1;
}
elsif (s/: alloc / /)
{
s/=.*//;
s/\(.*\)// if (! $lines);
($file, $size) = split;
$allocated{$file} += $size;
$count{$file} += 1;
}
}
if ($sortMethod == 0)
{
# print sorted by allocated amount
foreach (sort sortAllocated keys %allocated)
{
print $count{$_}, "\t", $allocated{$_}, "\t", $_, "\n";
}
}
else
{
# print sorted by # allocations
foreach (sort sortCount keys %count)
{
print $count{$_}, "\t", $allocated{$_}, "\t", $_, "\n";
}
}

Some files were not shown because too many files have changed in this diff Show More