jit refactoring branch

--HG--
branch : refac-jit
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/refac-jit%402369
This commit is contained in:
David Anderson
2008-07-06 04:49:55 +00:00
commit 2e7b6b5ba5
879 changed files with 297155 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
# (C)2004-2008 SourceMod Development Team
# Makefile written by David "BAILOPAN" Anderson
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
OBJECTS = main.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc-4.1
BINARY = vtablecheck
LINK += -L. -liberty -ldl
INCLUDE += -I.
CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
-Wno-uninitialized -mfpmath=sse -msse -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32
CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
################################################
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS += $(C_DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS += $(C_OPT_FLAGS)
endif
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
ifeq "$(GCC_VERSION)" "4"
CFLAGS += $(C_GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS)
endif
OBJ_LINUX := $(OBJECTS:%vm_engine.cpp=$(BIN_DIR)/%vm_engine.o)
OBJ_LINUX := $(OBJ_LINUX:%.cpp=$(BIN_DIR)/%.o)
OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
$(BIN_DIR)/%vm_engine.o: %vm_engine.cpp
$(CPP) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.c
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)
$(MAKE) -f Makefile sourcemod
sourcemod: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -o$(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f Makefile all DEBUG=true
default: all
clean:
rm -rf $(BIN_DIR)/$(BINARY)
+16
View File
@@ -0,0 +1,16 @@
#echo "sdktools.games.ep2.txt"
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer RemovePlayerItem
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer Weapon_GetSlot
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer Ignite
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer Extinguish
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer Teleport
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer CommitSuicide "(bool, bool)"
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer GetVelocity
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer EyeAngles
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer AcceptInput
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer KeyValue "(char const*, char const*)"
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer KeyValue "(char const*, float)"
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer KeyValue "(char const*, Vector const&)"
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer SetModel
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer Weapon_Equip
./vtablecheck ~/srcds/orangebox/dod/bin/server_i486.so _ZTV10CDODPlayer Activate
Binary file not shown.
+184
View File
@@ -0,0 +1,184 @@
#include <stdio.h>
#include <dlfcn.h>
#include "string.h"
#include "malloc.h"
extern "C" char * cplus_demangle(const char *, int);
#define DMGL_PARAMS (1 << 0)
struct VOffset
{
int linux_offset;
int windows_offset;
};
static bool FindVFunc(void *handle, void **vtable, const char* vtable_end, const char *class_function, const char *params, VOffset *offsets);
int main(int argc, char **argv)
{
void *handle;
void **pVtable;
handle = dlopen(argv[1], RTLD_NOW);
VOffset offsets;
char *params = NULL;
bool ret;
if (argc < 4)
{
fprintf(stderr, "Usage: <binary> <vtable start symbol> <function> <optional: params> <optional: vtable end symbol>\n");
return -1;
}
if (handle == NULL)
{
fprintf(stderr, "Failed to open server image, error [%s]\n", dlerror());
return -1;
}
pVtable = (void **)dlsym(handle, argv[2]);
if (pVtable == NULL)
{
fprintf(stderr, "Invalid vtable symbol \"%s\"\n", argv[2]);
return -1;
}
if (argc >= 5)
{
params = argv[4];
if (params[0] == '"')
{
params++;
}
int len = strlen(params)-1;
if (params[len] == '"')
{
params[len] = '\0';
}
if (params[0] == 0)
{
params = NULL;
}
}
if (argc == 6)
{
ret = FindVFunc(handle, pVtable, argv[5], argv[3], params, &offsets);
}
else
{
ret = FindVFunc(handle, pVtable, "_ZTI", argv[3], params, &offsets);
}
if (ret)
{
if (params != NULL)
{
printf("%s%s - Win: %i Linux : %i\n", argv[3], params, offsets.windows_offset, offsets.linux_offset);
}
else
{
printf("%s - Win: %i Linux : %i\n", argv[3], offsets.windows_offset, offsets.linux_offset);
}
return 0;
}
fprintf(stderr, "Failed to find function!");
return -1;
}
static bool FindVFunc(void *handle, void **vtable, const char* vtable_end, const char *class_function, const char *params, VOffset *offsets)
{
Dl_info d;
int linux_offset = -1;
int windows_offset = -1;
int overloads = 0;
int location = 0;
int start_offset = -1;
for (int i=0; i< 1000; i++)
{
void *FuncPtr = vtable[i];
int status = dladdr(FuncPtr, &d);
if (!status)
{
continue;
}
if (i > 1 && strncmp(d.dli_sname, vtable_end, strlen(vtable_end)) == 0)
{
break;
}
char *name = cplus_demangle(d.dli_sname, DMGL_PARAMS);
if (name == NULL)
{
printf("Demangling failed\n");
continue;
}
char *foundfunction = strpbrk(name, ":");
if (foundfunction == NULL)
{
//printf("Couldnt split function\n");
free(name);
continue;
}
//Skip both ':' chars
foundfunction += 2;
if (strncmp(foundfunction, class_function, strlen(class_function)) == 0 && foundfunction[strlen(class_function)] == '(')
{
//printf("Symbol: %s Demangled: %s Offset: %i\n", d.dli_sname, name, i);
//We have a pointer to a function, but it may be overloaded.
overloads++;
if (start_offset == -1)
{
start_offset = i-1;
}
char *foundparams = strpbrk(foundfunction, "(");
if (foundparams == NULL)
{
printf("ARGH\n");
free(name);
continue;
}
if(params == NULL || strcmp(foundparams, params) == 0)
{
//This is actually our function - So this is the linux offset
linux_offset = i;
location = overloads;
}
}
free(name);
}
windows_offset = (overloads-location) + start_offset;
dlclose(handle);
offsets->linux_offset = linux_offset - 2;
offsets->windows_offset = windows_offset - 2;
return true;
}
+17
View File
@@ -0,0 +1,17 @@
echo "sdktools.games.ep2.txt"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer RemovePlayerItem
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Weapon_GetSlot
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Ignite
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Extinguish
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Teleport
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer CommitSuicide "(bool, bool)"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer GetVelocity
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer EyeAngles
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer KeyValue "(char const*, char const*)"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer KeyValue "(char const*, float)"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer KeyValue "(char const*, Vector const&)"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer SetModel
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer AcceptInput
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Activate
echo "sm-tf2.games.txt"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer ForceRespawn
+199
View File
@@ -0,0 +1,199 @@
using System;
using System.IO;
using System.Diagnostics;
namespace builder
{
public abstract class ABuilder
{
public Config cfg;
public ABuilder()
{
}
public abstract bool BuildLibrary(Package pkg, Library lib);
public abstract string GetPawnCompilerName();
public bool CompilePlugin(Package pkg, Plugin pl)
{
string local_dir = Config.PathFormat("{0}/{1}/addons/sourcemod/scripting", cfg.pkg_path, pkg.GetBaseFolder());
string filepath = null;
if (pl.Folder != null)
{
filepath = Config.PathFormat("{0}/{1}", pl.Folder, pl.Source);
}
else
{
filepath = pl.Source;
}
ProcessStartInfo info = new ProcessStartInfo();
info.WorkingDirectory = local_dir;
info.FileName = Config.PathFormat("{0}/{1}", local_dir, GetPawnCompilerName());
info.Arguments = filepath + ".sp";
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
Process p = Process.Start(info);
string output = p.StandardOutput.ReadToEnd() + "\n";
output += p.StandardError.ReadToEnd();
p.WaitForExit();
p.Close();
Console.WriteLine("Debug: wd = " + info.WorkingDirectory + " fn = " + info.FileName + " arg = " + info.Arguments);
Console.WriteLine(output);
string binary = Config.PathFormat("{0}/{1}/addons/sourcemod/scripting/{2}.smx", cfg.pkg_path, pkg.GetBaseFolder(), pl.Source);
if (!File.Exists(binary))
{
Console.WriteLine("Could not find binary: " + binary);
return false;
}
string new_loc;
if (pl.disabled)
{
new_loc = Config.PathFormat("{0}/{1}/addons/sourcemod/plugins/disabled/{2}.smx", cfg.pkg_path, pkg.GetBaseFolder(), pl.Source);
}
else
{
new_loc = Config.PathFormat("{0}/{1}/addons/sourcemod/plugins/{2}.smx", cfg.pkg_path, pkg.GetBaseFolder(), pl.Source);
}
try
{
if (File.Exists(new_loc))
{
File.Delete(new_loc);
}
File.Move(binary, new_loc);
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
return false;
}
return true;
}
public bool CopyFile(Package pkg, string source, string dest)
{
string from = Config.PathFormat("{0}/{1}",
cfg.source_path,
source);
string to = Config.PathFormat("{0}/{1}/{2}",
cfg.pkg_path,
pkg.GetBaseFolder(),
dest);
File.Copy(from, to, true);
return true;
}
/** dest can be null to mean root base folder */
public void CopyFolder(Package pkg, string source, string dest, string [] omits)
{
string from_base = Config.PathFormat("{0}/{1}", cfg.source_path, source);
string to_base = null;
if (dest == null)
{
to_base = Config.PathFormat("{0}/{1}",
cfg.pkg_path,
pkg.GetBaseFolder());
}
else
{
to_base = Config.PathFormat("{0}/{1}/{2}",
cfg.pkg_path,
pkg.GetBaseFolder(),
dest);
}
string [] files = Directory.GetFiles(from_base);
string file;
for (int i=0; i<files.Length; i++)
{
file = Path.GetFileName(files[i]);
if (omits != null)
{
bool skip = false;
for (int j=0; j<omits.Length; j++)
{
if (file.CompareTo(omits[j]) == 0)
{
skip = true;
break;
}
}
if (skip)
{
continue;
}
}
dest = Config.PathFormat("{0}/{1}", to_base, file);
File.Copy(files[i], dest, true);
}
}
public void BuildPackage(Package pkg)
{
string path = Config.PathFormat("{0}/{1}", cfg.pkg_path, pkg.GetBaseFolder());
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
/* Create all dirs */
string [] paths = pkg.GetFolders();
for (int i=0; i<paths.GetLength(0); i++)
{
path = Config.PathFormat("{0}/{1}/{2}", cfg.pkg_path, pkg.GetBaseFolder(), paths[i]);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
/* Do primitive copies */
pkg.OnCopyFolders(this);
pkg.OnCopyFiles(this);
/* Do libraries */
Library [] libs = pkg.GetLibraries();
for (int i=0; i<libs.Length; i++)
{
if (libs[i].build_mode == BuildMode.BuildMode_Episode1)
{
continue;
}
if (!BuildLibrary(pkg, libs[i]))
{
throw new System.Exception("Failed to compile library: " + libs[i].binary_name);
}
}
/* Do plugins */
Plugin [] plugins = pkg.GetPlugins();
if (plugins != null)
{
for (int i=0; i<plugins.Length; i++)
{
if (!CompilePlugin(pkg, plugins[i]))
{
throw new System.Exception("Failed to compile plugin: " + plugins[i].Source);
}
}
}
}
}
}
+58
View File
@@ -0,0 +1,58 @@
using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]
+110
View File
@@ -0,0 +1,110 @@
using System;
using System.IO;
using System.Text;
namespace builder
{
public enum BasePlatform
{
Platform_Windows,
Platform_Linux
};
public class Config
{
public string source_path;
public string pkg_path;
public string builder_path;
public string build_options;
public string pdb_log_file;
public builder.BasePlatform Platform;
public Config()
{
if ((int)System.Environment.OSVersion.Platform == 128)
{
Platform = BasePlatform.Platform_Linux;
}
else
{
Platform = BasePlatform.Platform_Windows;
}
}
public static string PathFormat(string format, params string [] args)
{
string temp = string.Format(format, args);
return temp.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
}
public bool ReadFromFile(string file)
{
bool read = true;
StreamReader sr = null;
try
{
sr = new StreamReader(file);
string line;
string delim = "\t \n\r\v";
string split = "=";
while ( (line = sr.ReadLine()) != null )
{
line = line.Trim(delim.ToCharArray());
if (line.Length < 1 || line[0] == ';')
{
continue;
}
string [] s = line.Split(split.ToCharArray());
string key, val = "";
if (s.GetLength(0) >= 1)
{
key = s[0];
if (s.GetLength(0) >= 2)
{
for (int i=1; i<s.GetLength(0); i++)
{
val += s[i];
}
}
key = key.Trim(delim.ToCharArray());
val = val.Trim(delim.ToCharArray());
if (key.CompareTo("SourceBase") == 0)
{
source_path = val;
}
else if (key.CompareTo("OutputBase") == 0)
{
pkg_path = val;
}
else if (key.CompareTo("BuilderPath") == 0)
{
builder_path = val;
}
else if (key.CompareTo("BuildOptions") == 0)
{
build_options = val;
}
else if (key.CompareTo("PDBLog") == 0)
{
pdb_log_file = val;
}
}
}
}
catch (System.Exception e)
{
Console.WriteLine("Unable to read {0:s}: {1:s}", file, e.Message);
read = false;
}
if (sr != null)
{
sr.Close();
}
return read;
}
}
}
+118
View File
@@ -0,0 +1,118 @@
using System;
using System.IO;
using System.Diagnostics;
namespace builder
{
public class LinuxBuilder : ABuilder
{
public LinuxBuilder(Config _cfg)
{
cfg = _cfg;
}
public override string GetPawnCompilerName()
{
return "spcomp";
}
public override bool BuildLibrary(Package pkg, Library lib)
{
ProcessStartInfo info = new ProcessStartInfo();
string path = Config.PathFormat("{0}/{1}",
cfg.source_path,
lib.source_path);
/* PlatformExt ignored for us */
string binName = lib.binary_name;
if (!lib.is_executable)
{
if (lib.has_platform_ext)
{
binName += "_i486.so";
}
else
{
binName += ".so";
}
}
string output_folder = (lib.release_mode == ReleaseMode.ReleaseMode_Release) ? "Release" : "Debug";
if (lib.build_mode == BuildMode.BuildMode_Episode2)
{
output_folder += ".orangebox";
}
else if (lib.build_mode == BuildMode.BuildMode_OldMetamod)
{
output_folder += ".original";
}
string binpath = Config.PathFormat("{0}/{1}/{2}",
path,
output_folder,
binName);
if (File.Exists(binpath))
{
File.Delete(binpath);
}
string makefile_args = "";
if (lib.build_mode == BuildMode.BuildMode_Episode1)
{
makefile_args = null;
}
else if (lib.build_mode == BuildMode.BuildMode_Episode2)
{
makefile_args = "ENGINE=\"orangebox\"";
}
else if (lib.build_mode == BuildMode.BuildMode_OldMetamod)
{
makefile_args = "ENGINE=\"original\"";
}
/* Clean the project first */
info.WorkingDirectory = path;
info.FileName = cfg.builder_path;
info.Arguments = makefile_args + " clean";
info.UseShellExecute = false;
Process p = Process.Start(info);
p.WaitForExit();
p.Close();
/* Now build it */
info.WorkingDirectory = path;
info.FileName = cfg.builder_path;
info.Arguments = makefile_args;
info.UseShellExecute = false;
if (cfg.build_options != null)
{
info.Arguments += " " + cfg.build_options;
}
p = Process.Start(info);
p.WaitForExit();
p.Close();
if (!File.Exists(binpath))
{
return false;
}
path = Config.PathFormat("{0}/{1}/{2}/{3}",
cfg.pkg_path,
pkg.GetBaseFolder(),
lib.package_path,
binName);
File.Copy(binpath, path, true);
return true;
}
}
}
+50
View File
@@ -0,0 +1,50 @@
using System;
using System.IO;
using System.Diagnostics;
namespace builder
{
class Program
{
static void Main(string[] args)
{
if (args.GetLength(0) < 1)
{
System.Console.WriteLine("Usage: <config file>");
return;
}
Config cfg = new Config();
if (!cfg.ReadFromFile(args[0]))
{
return;
}
/* :TODO: Add path validation */
ABuilder bld = null;
if (cfg.Platform == BasePlatform.Platform_Linux)
{
bld = new LinuxBuilder(cfg);
}
else if (cfg.Platform == BasePlatform.Platform_Windows)
{
bld = new Win32Builder(cfg);
if (cfg.pdb_log_file != null && File.Exists(cfg.pdb_log_file))
{
File.Delete(cfg.pdb_log_file);
}
}
try
{
bld.BuildPackage(new PkgCore());
}
catch (System.Exception e)
{
Console.WriteLine("Build failed: " + e.Message);
}
}
}
}
+15
View File
@@ -0,0 +1,15 @@
CS = mcs
NAME = builder
BINARY = $(NAME).exe
OBJECTS = ABuilder.cs AssemblyInfo.cs Config.cs LinuxBuilder.cs Win32Builder.cs \
Package.cs PkgCore.cs Main.cs
default: all
all: $(OBJECTS)
$(CS) $(OBJECTS) -out:$(BINARY)
clean:
rm -rf $(BINARY)
+103
View File
@@ -0,0 +1,103 @@
using System;
namespace builder
{
public enum ReleaseMode : int
{
ReleaseMode_Release,
ReleaseMode_Debug,
};
public enum BuildMode : int
{
BuildMode_Simple,
BuildMode_OldMetamod,
BuildMode_Episode1,
BuildMode_Episode2
};
public class Library
{
public Library()
{
has_platform_ext = false;
is_executable = false;
release_mode = ReleaseMode.ReleaseMode_Release;
build_mode = BuildMode.BuildMode_Simple;
}
public string binary_name; /* Name of binary */
public string source_path; /* Local path to library build scripts */
public ReleaseMode release_mode; /* Release mode */
public BuildMode build_mode; /* Build mode */
public string package_path; /* Final relative path */
public bool has_platform_ext; /* Add extra platform extension? */
public string vcproj_name; /* Project file, NULL for standard */
public bool is_executable; /* If this is an EXE instead of a DLL */
};
public class Plugin
{
public Plugin(string file)
{
Source = file;
disabled = false;
}
public Plugin (string file, string folder)
{
Source = file;
Folder = folder;
disabled = false;
}
public Plugin (string file, bool is_disabled)
{
Source = file;
disabled = is_disabled;
}
public string Folder; /* Source folder relative to scripting (null for default) */
public string Source; /* Source file name */
public bool disabled; /* Is the plugin disabled? */
};
public abstract class Package
{
/**
* Must return the root compression point.
*/
public abstract void GetCompressBases(ref string path, ref string folder);
/**
* Must return the base package output folder.
*/
public abstract string GetBaseFolder();
/**
* Must return the list of folders to create.
*/
public abstract string [] GetFolders();
/**
* Called when file to file copies must be performed
*/
public abstract void OnCopyFiles(ABuilder builder);
/**
* Called when dir to dir copies must be performed
*/
public abstract void OnCopyFolders(ABuilder builder);
/**
* Called to build libraries
*/
public abstract Library [] GetLibraries();
/**
* Called to get package name
*/
public abstract string GetPackageName();
/**
* Called to get a plugin list
*/
public abstract Plugin [] GetPlugins();
}
}
+328
View File
@@ -0,0 +1,328 @@
using System;
using System.Collections;
namespace builder
{
public class PkgCore : Package
{
private ArrayList libraries;
private ArrayList plugins;
private ArrayList folders;
public PkgCore()
{
}
public override string GetBaseFolder()
{
return "base";
}
public override void GetCompressBases(ref string path, ref string folder)
{
path = "base";
folder = "addons";
}
public override string GetPackageName()
{
return "sourcemod-core";
}
/**
* Must return the list of folders to create.
*/
public override string [] GetFolders()
{
if (folders != null)
{
return (string [])folders.ToArray(typeof(string));
}
folders = new ArrayList();
folders.Add("addons/sourcemod/bin");
folders.Add("addons/sourcemod/plugins/disabled");
folders.Add("addons/sourcemod/gamedata");
folders.Add("addons/sourcemod/configs/geoip");
folders.Add("addons/sourcemod/translations");
folders.Add("addons/sourcemod/logs");
folders.Add("addons/sourcemod/extensions");
folders.Add("addons/sourcemod/data");
folders.Add("addons/sourcemod/scripting/include");
folders.Add("addons/sourcemod/scripting/admin-flatfile");
folders.Add("addons/sourcemod/scripting/adminmenu");
folders.Add("addons/sourcemod/scripting/testsuite");
folders.Add("cfg/sourcemod");
folders.Add("addons/sourcemod/configs/sql-init-scripts");
folders.Add("addons/sourcemod/configs/sql-init-scripts/mysql");
folders.Add("addons/sourcemod/configs/sql-init-scripts/sqlite");
//folders.Add("addons/sourcemod/extensions/games");
folders.Add("addons/sourcemod/scripting/basecommands");
folders.Add("addons/sourcemod/scripting/basecomm");
folders.Add("addons/sourcemod/scripting/funvotes");
folders.Add("addons/sourcemod/scripting/basevotes");
folders.Add("addons/sourcemod/scripting/basebans");
folders.Add("addons/sourcemod/scripting/funcommands");
folders.Add("addons/sourcemod/extensions/auto.1.ep1");
//folders.Add("addons/sourcemod/extensions/auto.2.ep1");
folders.Add("addons/sourcemod/extensions/auto.2.ep2");
folders.Add("addons/sourcemod/scripting/playercommands");
folders.Add("addons/metamod");
return (string [])folders.ToArray(typeof(string));
}
/**
* Called when file to file copies must be performed
*/
public override void OnCopyFiles(ABuilder builder)
{
builder.CopyFile(this, "sourcepawn/batchtool/compile.exe", "addons/sourcemod/scripting/compile.exe");
}
/**
* Called when dir to dir copies must be performed
*/
public override void OnCopyFolders(ABuilder builder)
{
builder.CopyFolder(this, "configs", "addons/sourcemod/configs", null);
builder.CopyFolder(this, "configs/geoip", "addons/sourcemod/configs/geoip", null);
builder.CopyFolder(this, "configs/cfg", "cfg/sourcemod", null);
builder.CopyFolder(this, "configs/metamod", "addons/metamod", null);
builder.CopyFolder(this,
"configs/sql-init-scripts",
"addons/sourcemod/configs/sql-init-scripts",
null);
builder.CopyFolder(this,
"configs/sql-init-scripts/mysql",
"addons/sourcemod/configs/sql-init-scripts/mysql",
null);
builder.CopyFolder(this,
"configs/sql-init-scripts/sqlite",
"addons/sourcemod/configs/sql-init-scripts/sqlite",
null);
string [] plugin_omits = new string[1];
plugin_omits[0] = "spcomp.exe";
string [] include_omits = new string[1];
include_omits[0] = "version.tpl";
builder.CopyFolder(this, "gamedata", "addons/sourcemod/gamedata", null);
builder.CopyFolder(this, "plugins", "addons/sourcemod/scripting", plugin_omits);
builder.CopyFolder(this, "plugins/include", "addons/sourcemod/scripting/include", include_omits);
builder.CopyFolder(this, "translations", "addons/sourcemod/translations", null);
builder.CopyFolder(this, "public/licenses", "addons/sourcemod", null);
builder.CopyFolder(this, "plugins/admin-flatfile", "addons/sourcemod/scripting/admin-flatfile", null);
builder.CopyFolder(this, "plugins/adminmenu", "addons/sourcemod/scripting/adminmenu", null);
builder.CopyFolder(this, "plugins/testsuite", "addons/sourcemod/scripting/testsuite", null);
builder.CopyFolder(this, "plugins/basecommands", "addons/sourcemod/scripting/basecommands", null);
builder.CopyFolder(this, "plugins/basecomm", "addons/sourcemod/scripting/basecomm", null);
builder.CopyFolder(this, "plugins/funvotes", "addons/sourcemod/scripting/funvotes", null);
builder.CopyFolder(this, "plugins/basevotes", "addons/sourcemod/scripting/basevotes", null);
builder.CopyFolder(this, "plugins/basebans", "addons/sourcemod/scripting/basebans", null);
builder.CopyFolder(this, "plugins/funcommands", "addons/sourcemod/scripting/funcommands", null);
builder.CopyFolder(this, "plugins/playercommands", "addons/sourcemod/scripting/playercommands", null);
}
/**
* Called to build libraries
*/
public override Library [] GetLibraries()
{
if (libraries != null)
{
return (Library [])libraries.ToArray(typeof(Library));
}
libraries = new ArrayList();
Library lib = new Library();
lib.package_path = "addons/sourcemod/bin";
lib.source_path = "loader";
lib.binary_name = "sourcemod_mm";
lib.vcproj_name = "loader";
lib.build_mode = BuildMode.BuildMode_Simple;
lib.has_platform_ext = true;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/bin";
lib.source_path = "core";
lib.binary_name = "sourcemod.1.ep1";
lib.vcproj_name = "sourcemod_mm";
lib.build_mode = BuildMode.BuildMode_OldMetamod;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/bin";
lib.source_path = "core";
lib.binary_name = "sourcemod.2.ep1";
lib.vcproj_name = "sourcemod_mm";
lib.build_mode = BuildMode.BuildMode_Episode1;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/bin";
lib.source_path = "core";
lib.binary_name = "sourcemod.2.ep2";
lib.vcproj_name = "sourcemod_mm";
lib.build_mode = BuildMode.BuildMode_Episode2;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/bin";
lib.source_path = "sourcepawn/jit/x86";
lib.binary_name = "sourcepawn.jit.x86";
lib.vcproj_name = "jit-x86";
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/scripting";
lib.source_path = "sourcepawn/compiler";
lib.binary_name = "spcomp";
lib.is_executable = true;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions";
lib.source_path = "extensions/geoip";
lib.binary_name = "geoip.ext";
lib.vcproj_name = "geoip";
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions";
lib.source_path = "extensions/bintools";
lib.binary_name = "bintools.ext";
lib.vcproj_name = "bintools";
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions";
lib.source_path = "extensions/mysql";
lib.binary_name = "dbi.mysql.ext";
lib.vcproj_name = "sm_mysql";
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions/auto.1.ep1";
lib.source_path = "extensions/sdktools";
lib.binary_name = "sdktools.ext";
lib.vcproj_name = "sdktools";
lib.build_mode = BuildMode.BuildMode_OldMetamod;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions/auto.2.ep1";
lib.source_path = "extensions/sdktools";
lib.binary_name = "sdktools.ext";
lib.vcproj_name = "sdktools";
lib.build_mode = BuildMode.BuildMode_Episode1;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions/auto.2.ep2";
lib.source_path = "extensions/sdktools";
lib.binary_name = "sdktools.ext";
lib.vcproj_name = "sdktools";
lib.build_mode = BuildMode.BuildMode_Episode2;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions";
lib.source_path = "extensions/sqlite";
lib.binary_name = "dbi.sqlite.ext";
lib.vcproj_name = "sm_sqlite";
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions/auto.1.ep1";
lib.source_path = "extensions/cstrike";
lib.binary_name = "game.cstrike.ext";
lib.vcproj_name = "cstrike";
lib.build_mode = BuildMode.BuildMode_OldMetamod;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions/auto.2.ep1";
lib.source_path = "extensions/cstrike";
lib.binary_name = "game.cstrike.ext";
lib.vcproj_name = "cstrike";
lib.build_mode = BuildMode.BuildMode_Episode1;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions";
lib.source_path = "extensions/topmenus";
lib.binary_name = "topmenus.ext";
lib.vcproj_name = "topmenus";
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions/auto.2.ep2";
lib.source_path = "extensions/tf2";
lib.binary_name = "game.tf2.ext";
lib.vcproj_name = "tf2";
lib.build_mode = BuildMode.BuildMode_Episode2;
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions";
lib.source_path = "extensions/regex";
lib.binary_name = "regex.ext";
lib.vcproj_name = "regex";
libraries.Add(lib);
lib = new Library();
lib.package_path = "addons/sourcemod/extensions";
lib.source_path = "extensions/clientprefs";
lib.binary_name = "clientprefs.ext";
lib.vcproj_name = "clientprefs";
libraries.Add(lib);
return (Library [])libraries.ToArray(typeof(Library));
}
/**
* Called to build plugins
*/
public override Plugin [] GetPlugins()
{
if (plugins != null)
{
return (Plugin [])plugins.ToArray(typeof(Plugin));
}
plugins = new ArrayList();
plugins.Add(new Plugin("admin-flatfile", "admin-flatfile"));
plugins.Add(new Plugin("adminhelp"));
plugins.Add(new Plugin("antiflood"));
plugins.Add(new Plugin("basecommands"));
plugins.Add(new Plugin("reservedslots"));
plugins.Add(new Plugin("basetriggers"));
plugins.Add(new Plugin("nextmap"));
plugins.Add(new Plugin("basechat"));
plugins.Add(new Plugin("funcommands"));
plugins.Add(new Plugin("basevotes"));
plugins.Add(new Plugin("funvotes"));
plugins.Add(new Plugin("admin-sql-prefetch", true));
plugins.Add(new Plugin("admin-sql-threaded", true));
plugins.Add(new Plugin("sql-admin-manager", true));
plugins.Add(new Plugin("basebans"));
plugins.Add(new Plugin("mapchooser", true));
plugins.Add(new Plugin("basecomm"));
plugins.Add(new Plugin("randomcycle", true));
plugins.Add(new Plugin("rockthevote", true));
plugins.Add(new Plugin("adminmenu"));
plugins.Add(new Plugin("playercommands"));
plugins.Add(new Plugin("clientprefs"));
plugins.Add(new Plugin("nominations", true));
return (Plugin [])plugins.ToArray(typeof(Plugin));
}
}
}
+116
View File
@@ -0,0 +1,116 @@
using System;
using System.IO;
using System.Diagnostics;
namespace builder
{
public class Win32Builder : ABuilder
{
public Win32Builder(Config _cfg)
{
cfg = _cfg;
}
public override string GetPawnCompilerName()
{
return "spcomp.exe";
}
public override bool BuildLibrary(Package pkg, Library lib)
{
ProcessStartInfo info = new ProcessStartInfo();
string path = Config.PathFormat("{0}/{1}/msvc8",
cfg.source_path,
lib.source_path);
/* PlatformExt ignored for us */
string binName = lib.binary_name + (lib.is_executable ? ".exe" : ".dll");
string config_name = "Unknown";
if (lib.release_mode == ReleaseMode.ReleaseMode_Release)
{
config_name = "Release";
}
else if (lib.release_mode == ReleaseMode.ReleaseMode_Debug)
{
config_name = "Debug";
}
if (lib.build_mode == BuildMode.BuildMode_Episode1)
{
config_name = config_name + " - Episode 1";
}
else if (lib.build_mode == BuildMode.BuildMode_Episode2)
{
config_name = config_name + " - Orange Box";
}
else if (lib.build_mode == BuildMode.BuildMode_OldMetamod)
{
config_name = config_name + " - Old Metamod";
}
string binpath = Config.PathFormat("{0}/{1}/{2}",
path,
config_name,
binName);
if (File.Exists(binpath))
{
File.Delete(binpath);
}
string project_file = null;
if (lib.vcproj_name != null)
{
project_file = lib.vcproj_name + ".vcproj";
}
else
{
project_file = lib.binary_name + ".vcproj";
}
info.WorkingDirectory = path;
info.FileName = cfg.builder_path;
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
if (cfg.build_options != null)
{
info.Arguments = cfg.build_options + " ";
}
info.Arguments += "/rebuild \"" + config_name + "\" " + project_file;
Process p = Process.Start(info);
Console.WriteLine(p.StandardOutput.ReadToEnd());
p.WaitForExit();
p.Close();
if (!File.Exists(binpath))
{
return false;
}
path = Config.PathFormat("{0}/{1}/{2}/{3}",
cfg.pkg_path,
pkg.GetBaseFolder(),
lib.package_path,
binName);
File.Copy(binpath, path, true);
/* On Windows we optionally log the PDB path */
if (!lib.is_executable && cfg.pdb_log_file != null)
{
FileStream fs = File.Open(cfg.pdb_log_file, FileMode.Append, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(binpath.Replace(".dll", ".pdb"));
sw.Close();
}
return true;
}
}
}
+4
View File
@@ -0,0 +1,4 @@
OutputBase = /home/dvander/bin
SourceBase = /home/dvander/sourcemod/trunk
BuilderPath = /usr/bin/make
+3
View File
@@ -0,0 +1,3 @@
OutputBase = c:\real\done
SourceBase = r:\sourcemod\trunk
BuilderPath = C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com
+130
View File
@@ -0,0 +1,130 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.10.6030"
SchemaVersion = "2.0"
ProjectGuid = "{BFC4EB78-4C3E-4C81-8EAD-5A1A2F126512}"
>
<Build>
<Settings
ApplicationIcon = ""
AssemblyKeyContainerName = ""
AssemblyName = "builder"
AssemblyOriginatorKeyFile = ""
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Exe"
PreBuildEvent = ""
PostBuildEvent = ""
RootNamespace = "builder"
RunPostBuildEvent = "OnBuildSuccess"
StartupObject = ""
>
<Config
Name = "Debug"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "DEBUG;TRACE"
DocumentationFile = ""
DebugSymbols = "true"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "false"
OutputPath = "bin\Debug\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
<Config
Name = "Release"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "TRACE"
DocumentationFile = ""
DebugSymbols = "false"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "true"
OutputPath = "bin\Release\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
</Settings>
<References>
<Reference
Name = "System"
AssemblyName = "System"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
/>
<Reference
Name = "System.Data"
AssemblyName = "System.Data"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
/>
<Reference
Name = "System.XML"
AssemblyName = "System.XML"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
/>
</References>
</Build>
<Files>
<Include>
<File
RelPath = "ABuilder.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "AssemblyInfo.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Config.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "LinuxBuilder.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Main.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Package.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "PkgCore.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Win32Builder.cs"
SubType = "Code"
BuildAction = "Compile"
/>
</Include>
</Files>
</CSHARP>
</VisualStudioProject>
+23
View File
@@ -0,0 +1,23 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "builder", "builder.csproj", "{BFC4EB78-4C3E-4C81-8EAD-5A1A2F126512}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{BFC4EB78-4C3E-4C81-8EAD-5A1A2F126512}.Debug.ActiveCfg = Debug|.NET
{BFC4EB78-4C3E-4C81-8EAD-5A1A2F126512}.Debug.Build.0 = Debug|.NET
{BFC4EB78-4C3E-4C81-8EAD-5A1A2F126512}.Release.ActiveCfg = Release|.NET
{BFC4EB78-4C3E-4C81-8EAD-5A1A2F126512}.Release.Build.0 = Release|.NET
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal
+2
View File
@@ -0,0 +1,2 @@
g++ -I../../core ../../core/sm_crc32.cpp main.cpp -ocrc32
+46
View File
@@ -0,0 +1,46 @@
#include <stdio.h>
#include <stdlib.h>
#include <sm_crc32.h>
int main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "Usage: crc32 <file>\n");
exit(1);
}
FILE *fp = fopen(argv[1], "rb");
if (!fp)
{
fprintf(stderr, "Could not open file: %s\n", argv[1]);
exit(1);
}
fseek(fp, 0, SEEK_END);
size_t size = ftell(fp);
if (!size)
{
fprintf(stderr, "Cannot checksum an empty file.\n");
exit(1);
}
fseek(fp, 0, SEEK_SET);
void *buffer = malloc(size);
if (!buffer)
{
fprintf(stderr, "Unable to allocate %d bytes of memory.\n", size);
exit(1);
}
fread(buffer, size, 1, fp);
unsigned int crc32 = UTIL_CRC32(buffer, size);
free(buffer);
fclose(fp);
fprintf(stdout, "%08X\n", crc32);
return 0;
}
+76
View File
@@ -0,0 +1,76 @@
# (C)2004-2008 SourceMod Development Team
# Makefile written by David "BAILOPAN" Anderson
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
OBJECTS = smud.cpp smud_connections.cpp smud_threads.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc-4.1
BINARY = daemon
LINK += -lpthread -static-libgcc
INCLUDE += -I.
CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
-Wno-uninitialized -mfpmath=sse -msse -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32
CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
################################################
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS += $(C_DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS += $(C_OPT_FLAGS)
endif
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
ifeq "$(GCC_VERSION)" "4"
CFLAGS += $(C_GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS)
endif
OBJ_LINUX := $(OBJECTS:%vm_engine.cpp=$(BIN_DIR)/%vm_engine.o)
OBJ_LINUX := $(OBJ_LINUX:%.cpp=$(BIN_DIR)/%.o)
OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
$(BIN_DIR)/%vm_engine.o: %vm_engine.cpp
$(CPP) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.c
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)
$(MAKE) -f Makefile sourcemod
sourcemod: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -lstdc++ -o$(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f Makefile all DEBUG=true
default: all
clean:
rm -rf $(BIN_DIR)/$(BINARY)
+130
View File
@@ -0,0 +1,130 @@
#include "smud.h"
#include "smud_threads.h"
#define LISTEN_PORT 6500
#define LISTEN_QUEUE_LENGTH 6
char fileNames[NUM_FILES][30] = {
"core.games.txt",
"sdktools.games.txt",
"sdktools.games.ep2.txt",
"sm-cstrike.games.txt",
"sm-tf2.games.txt",
};
void *fileLocations[NUM_FILES];
int fileLength[NUM_FILES];
int main(int argc, char **argv)
{
ThreadPool *pool;
struct protoent *pProtocol;
struct sockaddr_in serverAddress;
struct sockaddr_in clientAddress;
int serverSocket;
int clientSocket;
int addressLen;
int opts;
int file;
char filename[100];
struct stat sbuf;
printf("Loading Gamedata files into memory\n");
for (int i=0; i<NUM_FILES; i++)
{
snprintf(filename, sizeof(filename), "./md5/%s", fileNames[i]);
file = open(filename, O_RDWR);
if (!file)
{
return 1;
}
if (stat(filename, &sbuf) == -1)
{
return 1;
}
if ((fileLocations[i] = mmap(NULL, sbuf.st_size, PROT_READ, MAP_SHARED, file, 0)) == (caddr_t)(-1))
{
return 1;
}
fileLength[i] = sbuf.st_size;
printf("Initialised file of %s of length %i\n", fileNames[i], fileLength[i]);
}
printf("Initializing Thread Pool\n");
pool = new ThreadPool();
if (!pool->Start())
{
return 1;
}
printf("Create Server Socket\n");
memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = INADDR_ANY;
serverAddress.sin_port = htons(LISTEN_PORT);
pProtocol = getprotobyname("tcp");
if (pProtocol == NULL)
{
return 1;
}
serverSocket = socket(AF_INET, SOCK_STREAM, pProtocol->p_proto);
if (serverSocket < 0)
{
return 1;
}
opts = 1;
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &opts, sizeof(opts));
if (bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0)
{
return 1;
}
if (listen(serverSocket, LISTEN_QUEUE_LENGTH) < 0)
{
return 1;
}
printf("Entering Main Loop\n");
while (1)
{
addressLen = sizeof(clientAddress);
if ( (clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddress, (socklen_t *)&addressLen)) < 0)
{
continue;
}
opts = fcntl(clientSocket, F_GETFL, 0);
if (fcntl(clientSocket, F_SETFL, opts|O_NONBLOCK) < 0)
{
closesocket(clientSocket);
continue;
}
printf("Connection Received!\n");
pool->AddConnection(clientSocket);
}
delete pool;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef _INCLUDE_SMUD_MAIN_H_
#define _INCLUDE_SMUD_MAIN_H_
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#define closesocket close
#define NUM_FILES 5
extern char fileNames[NUM_FILES][30];
extern void *fileLocations[NUM_FILES];
extern int fileLength[NUM_FILES];
#endif //_INCLUDE_SMUD_MAIN_H_
+404
View File
@@ -0,0 +1,404 @@
#include "smud_connections.h"
#include "smud.h"
ConnectionPool::ConnectionPool()
{
pthread_mutex_init(&m_AddLock, NULL);
m_timeOut = 1000;
}
ConnectionPool::~ConnectionPool()
{
pthread_mutex_destroy(&m_AddLock);
}
void ConnectionPool::AddConnection( int fd )
{
smud_connection *connection = new smud_connection(fd);
pthread_mutex_lock(&m_AddLock);
m_AddQueue.push_back(connection);
pthread_mutex_unlock(&m_AddLock);
printf("New Connection Added\n");
}
void ConnectionPool::Process( bool *terminate )
{
struct timespec ts_wait;
ts_wait.tv_sec = 0;
ts_wait.tv_nsec = 50000000; /* 50ms */
std::list<smud_connection *>::iterator iter;
smud_connection *con = NULL;
while (1)
{
if (*terminate)
{
return;
}
iter = m_Links.begin();
QueryResult result = QueryResult_Continue;
int pollReturn = 0;
/* Add all connections that want processing to the sets */
while (iter != m_Links.end())
{
con = (smud_connection *)*iter;
pollReturn = poll(&(con->pollData), 1, 0);
if (pollReturn == -1)
{
//Something went badly wrong or the connection closed.
result = QueryResult_Complete;
}
else if (pollReturn == 1)
{
//Poll returns the number of sockets available (which can only ever be 1)
result = ProcessConnection(con);
}
if (result == QueryResult_Complete)
{
iter = m_Links.erase(iter);
closesocket(con->fd);
delete con;
printf("Connection Completed!\n");
continue;
}
iter++;
}
/* Add new items to process */
iter = m_Links.end();
pthread_mutex_lock(&m_AddLock);
m_Links.splice(iter, m_AddQueue);
pthread_mutex_unlock(&m_AddLock);
nanosleep(&ts_wait, NULL);
}
}
QueryResult ConnectionPool::ProcessConnection( smud_connection *con )
{
switch (con->state)
{
case ConnectionState_ReadQueryHeader:
{
ReadQueryHeader(con);
break;
}
case ConnectionState_ReadQueryData:
{
ReadQueryContent(con);
break;
}
case ConnectionState_ReplyQuery:
{
ReplyQuery(con);
break;
}
case ConnectionState_SendingFiles:
{
SendFile(con);
break;
}
case ConnectionState_SendUnknownList:
{
SendUnknownList(con);
break;
}
case ConnectionState_Complete:
{
break;
}
}
if (con->state == ConnectionState_Complete)
{
printf("Ending connection because it marked itself as finished\n");
return QueryResult_Complete;
}
if (con->start + m_timeOut < time(NULL))
{
printf("Ending connection because it has passed maximum allowed time\n");
return QueryResult_Complete;
}
return QueryResult_Continue;
}
void ConnectionPool::ReadQueryHeader( smud_connection *con )
{
char data[11];
if (recv(con->fd, data, sizeof(data), 0) == -1)
{
if (errno != EAGAIN && errno != EWOULDBLOCK)
{
con->state = ConnectionState_Complete;
}
return;
}
if (data[0] != 'A' || data[1] != 'G')
{
con->state = ConnectionState_Complete;
return;
}
//Ignore the next 8 bytes for the moment. Versioning data is currently unused
// uint16[4] - source version major/minor/something/rev
con->sentSums = data[10];
con->state = ConnectionState_ReadQueryData;
printf("Query Header Read Complete, %i md5's expected\n", con->sentSums);
}
void ConnectionPool::ReplyQuery(smud_connection *con)
{
char data[12];
data[0] = 'A';
data[1] = 'G';
data[2] = (char)Update_Unknown; //unused versioning crap
*(short *)&data[3] = 1;
*(short *)&data[5] = 0;
*(short *)&data[7] = 0;
*(short *)&data[9] = 3;
data[11] = (char)con->sendCount;
if (send(con->fd, data, sizeof(data), 0) == -1)
{
if (errno != EAGAIN && errno != EWOULDBLOCK)
{
con->state = ConnectionState_Complete;
}
return;
}
//Now we need more send sub functions for all the damn files. Geh.
//Alternatively we could just send all at once here. Could make for a damn big query. 100k anyone?
con->state = ConnectionState_SendingFiles;
printf("Query Reply Header Complete\n");
}
void ConnectionPool::ReadQueryContent( smud_connection *con )
{
char *data = new char[16*(con->sentSums)]();
if (recv(con->fd, data, 16*(con->sentSums), 0) == -1)
{
if (errno != EAGAIN && errno != EWOULDBLOCK)
{
con->state = ConnectionState_Complete;
}
delete [] data;
return;
}
con->shouldSend = new MD5Status[con->sentSums]();
con->fileLocation = new int[con->sentSums]();
con->headerSent = new bool[con->sentSums]();
for (int i=0; i<con->sentSums; i++)
{
con->fileLocation[i] = -1;
con->shouldSend[i] = GetMD5UpdateStatus(data + (16*i), con, i);
if (con->shouldSend[i] == MD5Status_NeedsUpdate)
{
printf("File %i needs updating\n", i);
con->sendCount++;
con->headerSent[i] = false;
continue;
}
if (con->shouldSend[i] == MD5Status_Unknown)
{
printf("File %i is unknown\n", i);
con->unknownCount++;
}
}
con->state = ConnectionState_ReplyQuery;
con->pollData.events = POLLOUT;
delete [] data;
printf("Query Data Read Complete\n");
}
MD5Status ConnectionPool::GetMD5UpdateStatus( const char *md5 , smud_connection *con, int fileNum)
{
//Try find a file with this name in some directory.
char path[100] = "./md5/";
char temp[4];
char md5String[33] = "";
for (int i=0; i<16; i++)
{
snprintf(temp, sizeof(temp), "%02x", (unsigned char)md5[i]);
strcat(md5String, temp);
}
strcat(path, md5String);
printf("checking for file \"%s\"\n", path);
FILE *file = fopen(path, "r");
if (file == NULL)
{
printf("Couldn't find file!\n");
return MD5Status_Unknown;
}
char latestMD5[33];
fgets(latestMD5, 33, file);
printf("Latest md5 is: %s\n", latestMD5);
if (strcmp(latestMD5, md5String) == 0)
{
return MD5Status_Current;
}
char filename[100];
filename[0] = '\n';
while (filename[0] == '\n')
{
fgets(filename, sizeof(filename), file);
}
if (filename[strlen(filename)-1] == '\n')
{
filename[strlen(filename)-1] = '\0';
}
printf("Filename is %s\n", filename);
//We now need to match this filename with one of our mmap'd files in memory and store it until send gets called.
for (int i=0; i<NUM_FILES; i++)
{
if (strcmp(fileNames[i], filename) == 0)
{
con->fileLocation[fileNum] = i;
printf("File %i mapped to local file %i\n", fileNum, i);
return MD5Status_NeedsUpdate;
}
}
return MD5Status_Unknown;
}
void ConnectionPool::SendFile( smud_connection *con )
{
//Find the next file to send.
while (con->currentFile < con->sentSums &&
con->shouldSend[con->currentFile] != MD5Status_NeedsUpdate)
{
con->currentFile++;
}
//All files have been sent.
if (con->currentFile >= con->sentSums)
{
printf("All files sent!\n");
con->state = ConnectionState_SendUnknownList;
return;
}
void *file = fileLocations[con->fileLocation[con->currentFile]];
int filelength = fileLength[con->fileLocation[con->currentFile]];
printf("Sending file of length %i\n", filelength);
printf("Current file index is: %i, maps to file index: %i\n", con->currentFile, con->fileLocation[con->currentFile]);
if (!con->headerSent[con->currentFile])
{
char buffer[5];
buffer[0] = con->currentFile;
*((int *)&buffer[1]) = filelength;
if (send(con->fd, buffer, 5, 0) == -1)
{
if (errno != EAGAIN && errno != EWOULDBLOCK)
{
con->state = ConnectionState_Complete;
}
return;
}
con->headerSent[con->currentFile] = true;
}
if (send(con->fd, file, filelength, 0) == -1)
{
if (errno != EAGAIN && errno != EWOULDBLOCK)
{
con->state = ConnectionState_Complete;
}
return;
}
con->currentFile++;
printf("Sent a file!: %s\n", fileNames[con->fileLocation[con->currentFile-1]]);
}
void ConnectionPool::SendUnknownList( smud_connection *con )
{
int size = con->unknownCount+1;
char *packet = new char[size]();
packet[0] = con->unknownCount;
printf("%i Files are unknown\n", con->unknownCount);
int i=1;
for (int j=0; j<con->sentSums; j++)
{
if (con->shouldSend[j] == MD5Status_Unknown)
{
packet[i] = j;
i++;
}
}
if (send(con->fd, packet, size, 0) == -1)
{
if (errno != EAGAIN && errno != EWOULDBLOCK)
{
con->state = ConnectionState_Complete;
}
return;
}
con->state = ConnectionState_Complete;
printf("Unknown's Sent\n");
}
+109
View File
@@ -0,0 +1,109 @@
#ifndef _INCLUDE_SMUD_CONNECTION_H_
#define _INCLUDE_SMUD_CONNECTION_H_
#include "smud.h"
#include <list>
#include "poll.h"
enum ConnectionState
{
ConnectionState_ReadQueryHeader,
ConnectionState_ReadQueryData,
ConnectionState_ReplyQuery,
ConnectionState_SendingFiles,
ConnectionState_SendUnknownList,
ConnectionState_Complete,
};
enum QueryResult
{
QueryResult_Continue,
QueryResult_Complete,
};
enum MD5Status
{
MD5Status_Unknown,
MD5Status_Current,
MD5Status_NeedsUpdate,
};
enum UpdateStatus
{
Update_Unknown = 0, /* Version wasn't recognised or version querying is unsupported */
Update_Current = 1, /* Server is running latest version */
Update_NewBuild = 2, /* Server is on a svn release and a newer version is available */
Update_MinorAvailable = 3, /* Server is on a release and a minor release has superceeded it */
Update_MajorAvailable = 4, /* Server is on a release and a major release has superceeded it */
Update_CriticalAvailable = 5, /* A critical update has been released (security fixes etc) */
};
struct smud_connection
{
smud_connection(int fd)
{
shouldSend = NULL;
fileLocation = NULL;
headerSent = NULL;
sentSums = 0;
sendCount = 0;
currentFile = 0;
unknownCount = 0;
pollData.events = POLLIN;
start = time(NULL);
state = ConnectionState_ReadQueryHeader;
this->fd = fd;
pollData.fd = fd;
}
~smud_connection()
{
if (shouldSend != NULL)
delete [] shouldSend;
if (fileLocation != NULL)
delete [] fileLocation;
if (headerSent != NULL)
delete [] headerSent;
}
int fd; /** Socket file descriptor */
time_t start; /** The time this connection was received (for timeouts) */
ConnectionState state; /** How far through processing the connection we are */
uint8_t sentSums; /** Number of MD5 Sums sent from the client */
MD5Status *shouldSend; /** Arrays of statuses for each sum */
int *fileLocation; /** Array of indexes into the global file list for each sum (only valid if shouldSend[i] == MD5Status_NeedsUpdate) */
bool *headerSent; /** Has the header been sent yet for each sum? Header == file index and size */
int sendCount; /** Number of files that need to be sent */
int unknownCount; /** Number of files that were unknown */
int currentFile; /** Current file being sent (index into the above 3 arrays) */
pollfd pollData; /** Data to be passed into poll() */
};
class ConnectionPool
{
public:
ConnectionPool();
~ConnectionPool();
public:
void AddConnection(int fd);
void Process(bool *terminate);
private:
QueryResult ProcessConnection(smud_connection *con);
void ReadQueryHeader(smud_connection *con);
void ReadQueryContent(smud_connection *con);
void ReplyQuery(smud_connection *con);
void SendFile(smud_connection *con);
void SendUnknownList(smud_connection *con);
MD5Status GetMD5UpdateStatus(const char *md5, smud_connection *con, int fileNum);
private:
std::list<smud_connection *> m_Links;
std::list<smud_connection *> m_AddQueue;
pthread_mutex_t m_AddLock;
time_t m_timeOut;
};
#endif //_INCLUDE_SMUD_CONNECTION_H_
+86
View File
@@ -0,0 +1,86 @@
#include "smud_threads.h"
ThreadPool::ThreadPool()
{
}
ThreadPool::~ThreadPool()
{
}
bool ThreadPool::Start()
{
m_pWorker = new ThreadWorker();
if (!m_pWorker->Start())
{
delete m_pWorker;
return false;
}
return true;
}
void ThreadPool::Stop()
{
m_pWorker->CancelAndWait();
delete m_pWorker;
}
void ThreadPool::AddConnection(int fd)
{
m_pWorker->AddConnection(fd);
}
ThreadWorker::ThreadWorker() : m_bShouldCancel(false)
{
}
ThreadWorker::~ThreadWorker()
{
}
bool ThreadWorker::Start()
{
m_pPool = new ConnectionPool();
pthread_mutex_init(&m_NotifyLock, NULL);
pthread_cond_init(&m_Notify, NULL);
if (pthread_create(&m_Thread, NULL, ThreadCallback, this) != 0)
{
return false;
}
return true;
}
void ThreadWorker::CancelAndWait()
{
m_bShouldCancel = true;
pthread_join(m_Thread, NULL);
pthread_cond_destroy(&m_Notify);
pthread_mutex_destroy(&m_NotifyLock);
delete m_pPool;
}
void ThreadWorker::AddConnection( int fd )
{
m_pPool->AddConnection(fd);
}
void ThreadWorker::Process()
{
m_pPool->Process(&m_bShouldCancel);
}
void *ThreadCallback(void *data)
{
((ThreadWorker *)data)->Process();
pthread_exit(NULL);
}
+41
View File
@@ -0,0 +1,41 @@
#ifndef _INCLUDE_SMUD_H_
#define _INCLUDE_SMUD_H_
#include "smud.h"
#include "smud_connections.h"
void *ThreadCallback(void *data);
class ThreadWorker
{
public:
ThreadWorker();
~ThreadWorker();
public:
bool Start();
void CancelAndWait();
void AddConnection(int fd);
void Process();
private:
ConnectionPool *m_pPool;
pthread_t m_Thread;
pthread_mutex_t m_NotifyLock;
pthread_cond_t m_Notify;
bool m_bShouldCancel;
};
class ThreadPool
{
public:
ThreadPool();
~ThreadPool();
public:
void AddConnection(int fd);
bool Start();
void Stop();
private:
ThreadWorker *m_pWorker;
};
#endif //_INCLUDE_SMUD_H_
+30
View File
@@ -0,0 +1,30 @@
#!/bin/bash
FILENAME=""
SUMSFILE=""
if [ -n "$1" ]
then
FILENAME="$1.txt"
SUMSFILE="$1.sums"
else
echo "Need to specify a gamedata filename"
exit -1
fi
if [ -s $FILENAME ]
then
#run ./gamedatamd5 on this file and pipe output+filename into $1.sums
MD5=`./gamedatamd5 $FILENAME`
#need to stop here if gamedatamd5 failed. (returns -1 and prints to stderr)
echo "$MD5" > "$SUMSFILE"
echo "$FILENAME" >> "$SUMSFILE"
ln -s "$SUMSFILE" "$MD5"
exit 0
fi
echo "File $FILENAME not found!"
exit -1
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fetchdlls", "fetchdlls.vcproj", "{3C1C562B-1080-445F-A632-EA9EC9793389}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3C1C562B-1080-445F-A632-EA9EC9793389}.Debug|Win32.ActiveCfg = Debug|Win32
{3C1C562B-1080-445F-A632-EA9EC9793389}.Debug|Win32.Build.0 = Debug|Win32
{3C1C562B-1080-445F-A632-EA9EC9793389}.Release|Win32.ActiveCfg = Release|Win32
{3C1C562B-1080-445F-A632-EA9EC9793389}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+196
View File
@@ -0,0 +1,196 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="fetchdlls"
ProjectGUID="{3C1C562B-1080-445F-A632-EA9EC9793389}"
RootNamespace="fetchdlls"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
UseOfATL="0"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dbghelp.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dbghelp.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+192
View File
@@ -0,0 +1,192 @@
#include <stdio.h>
#include <windows.h>
#include <DbgHelp.h>
void mdmp_string(void *mdmp, RVA addr, char *buffer, size_t maxlength)
{
int len;
MINIDUMP_STRING *str;
str = (MINIDUMP_STRING *)((char *)mdmp + addr);
len = WideCharToMultiByte(CP_UTF8,
0,
str->Buffer,
str->Length / sizeof(WCHAR),
buffer,
maxlength,
NULL,
NULL);
buffer[len] = '\0';
}
int find_revision(const char *version, MINIDUMP_MODULE *module, const char *name)
{
FILE *fp;
char msg[255];
size_t i, len;
char path[255];
char buffer[3000];
int last_revision;
len = _snprintf(path, sizeof(path), "%s", name);
for (i = 0; i < len; i++)
{
if (path[i] == '\\')
{
path[i] = '/';
}
}
DeleteFile("_svnlog.txt");
_snprintf(buffer,
sizeof(buffer),
"svn log svn://svn.alliedmods.net/svnroot/Packages/sourcemod/sourcemod-%d.%d/windows/base/addons/sourcemod/%s > _svnlog.txt",
(module->VersionInfo.dwFileVersionMS >> 16),
(module->VersionInfo.dwFileVersionMS & 0xFFFF),
path);
system(buffer);
if ((fp = fopen("_svnlog.txt", "rt")) == NULL)
{
return -1;
}
_snprintf(msg,
sizeof(msg),
"sourcemod-%s",
version);
while (fgets(buffer, sizeof(buffer), fp) != NULL)
{
if (buffer[0] == 'r')
{
last_revision = atoi(&buffer[1]);
}
else if (strstr(buffer, msg) != NULL)
{
fclose(fp);
_snprintf(buffer,
sizeof(buffer),
"svn export -q -r %d svn://svn.alliedmods.net/svnroot/Packages/sourcemod/sourcemod-%d.%d/windows/base/addons/sourcemod/%s",
last_revision,
(module->VersionInfo.dwFileVersionMS >> 16),
(module->VersionInfo.dwFileVersionMS & 0xFFFF),
path);
system(buffer);
return last_revision;
}
}
fclose(fp);
return -1;
}
int main(int argc, char **argv)
{
int rev;
ULONG32 m;
LPVOID mdmp;
HANDLE hFile;
const char *name;
ULONG stream_size;
char name_buf[255];
HANDLE hFileMapping;
MINIDUMP_MODULE *module;
MINIDUMP_DIRECTORY *dir;
MINIDUMP_MODULE_LIST *modules;
if (argc < 3)
{
fprintf(stderr, "Usage: <build> <mdmp>\n");
exit(-1);
}
if ((hFile = CreateFile(argv[2],
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL))
== INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Could not open file (error %d)\n", GetLastError());
exit(-1);
}
hFileMapping = CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
0,
0,
NULL);
if (hFileMapping == NULL)
{
fprintf(stderr, "Could not open file mapping (error %d)\n", GetLastError());
CloseHandle(hFile);
exit(-1);
}
mdmp = MapViewOfFile(hFileMapping,
FILE_MAP_READ,
0,
0,
0);
if (mdmp == NULL)
{
fprintf(stderr, "Could not create map view (error %d)\n", GetLastError());
CloseHandle(hFileMapping);
CloseHandle(hFile);
exit(-1);
}
if (!MiniDumpReadDumpStream(mdmp,
ModuleListStream,
&dir,
(void **)&modules,
&stream_size))
{
fprintf(stderr, "Could not read the module list stream.\n");
UnmapViewOfFile(mdmp);
CloseHandle(hFileMapping);
CloseHandle(hFile);
}
for (m = 0; m < modules->NumberOfModules; m++)
{
module = &modules->Modules[m];
mdmp_string(mdmp, module->ModuleNameRva, name_buf, sizeof(name_buf));
if ((name = strstr(name_buf, "sourcemod\\")) != NULL)
{
name += 10;
fprintf(stdout,
"looking for: %s (%d.%d.%d.%d of build %s)... ",
name,
(module->VersionInfo.dwFileVersionMS >> 16),
(module->VersionInfo.dwFileVersionMS & 0xFFFF),
(module->VersionInfo.dwFileVersionLS >> 16),
(module->VersionInfo.dwFileVersionLS & 0xFFFF),
argv[1]
);
fflush(stdout);
if ((rev = find_revision(argv[1], module, name)) == -1)
{
fprintf(stdout, "not found :(\n");
continue;
}
fprintf(stdout, "downloaded! (pkgrev %d)\n", rev);
}
}
UnmapViewOfFile(mdmp);
CloseHandle(hFileMapping);
CloseHandle(hFile);
return 0;
}
+74
View File
@@ -0,0 +1,74 @@
# (C)2004-2008 SourceMod Development Team
# Makefile written by David "BAILOPAN" Anderson
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
OBJECTS = main.cpp TextParsers.cpp sm_memtable.cpp md5.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc-4.1
BINARY = gamedatamd5
INCLUDE += -I. -I../../public -I../../public/sourcepawn
CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
-Wno-uninitialized -mfpmath=sse -msse -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32
CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
################################################
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS += $(C_DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS += $(C_OPT_FLAGS)
endif
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
ifeq "$(GCC_VERSION)" "4"
CFLAGS += $(C_GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS)
endif
OBJ_LINUX := $(OBJECTS:%vm_engine.cpp=$(BIN_DIR)/%vm_engine.o)
OBJ_LINUX := $(OBJ_LINUX:%.cpp=$(BIN_DIR)/%.o)
OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
$(BIN_DIR)/%vm_engine.o: %vm_engine.cpp
$(CPP) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.c
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)
$(MAKE) -f Makefile sourcemod
sourcemod: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -lstdc++ -o$(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f Makefile all DEBUG=true
default: all
clean:
rm -rf $(BIN_DIR)/$(BINARY)
File diff suppressed because it is too large Load Diff
+87
View File
@@ -0,0 +1,87 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
#define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
#include "ITextParsers.h"
#include "main.h"
using namespace SourceMod;
/**
* @param void * IN: Stream pointer
* @param char * IN/OUT: Stream buffer
* @param size_t IN: Maximum size of buffer
* @param unsigned int * OUT: Number of bytes read (0 = end of stream)
* @return True on success, false on failure
*/
typedef bool (*STREAMREADER)(void *, char *, size_t, unsigned int *);
class TextParsers : public ITextParsers
{
public:
TextParsers();
public:
bool ParseFile_INI(const char *file,
ITextListener_INI *ini_listener,
unsigned int *line,
unsigned int *col);
SMCError ParseFile_SMC(const char *file,
ITextListener_SMC *smc_listener,
SMCStates *states);
SMCError ParseSMCFile(const char *file,
ITextListener_SMC *smc_listener,
SMCStates *states,
char *buffer,
size_t maxsize);
unsigned int GetUTF8CharBytes(const char *stream);
const char *GetSMCErrorString(SMCError err);
bool IsWhitespace(const char *stream);
private:
SMCError ParseString_SMC(const char *stream,
ITextListener_SMC *smc,
SMCStates *states);
SMCError ParseStream_SMC(void *stream,
STREAMREADER srdr,
ITextListener_SMC *smc,
SMCStates *states);
};
extern TextParsers g_TextParser;
#endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_H_
+45
View File
@@ -0,0 +1,45 @@
#include "main.h"
#include <stdarg.h>
BuildMD5ableBuffer g_MD5Builder;
int main(int argc, char **argv)
{
SMCStates states;
SMCError error;
if (argc < 2)
{
fprintf(stderr, "Usage: <file>\n");
return -1;
}
error = g_TextParser.ParseFile_SMC(argv[1], &g_MD5Builder, &states);
if (error == SMCError_Okay)
{
printf("%s", g_MD5Builder.GetMD5String());
return 0;
}
fprintf(stderr, "Failed to parse file, Error %i at line %i and col %i\n", error, states.line, states.col);
return -1;
}
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
size_t len = vsnprintf(buffer, maxlength, fmt, ap);
va_end(ap);
if (len >= maxlength)
{
buffer[maxlength - 1] = '\0';
return (maxlength - 1);
}
else
{
return len;
}
}
+88
View File
@@ -0,0 +1,88 @@
#ifndef _INCLUDE_GAMEDATAMD5_MAIN_H_
#define _INCLUDE_GAMEDATAMD5_MAIN_H_
#include "TextParsers.h"
#include "sm_memtable.h"
#include "md5.h"
using namespace SourceMod;
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
class BuildMD5ableBuffer : public ITextListener_SMC
{
public:
BuildMD5ableBuffer()
{
stringTable = new BaseStringTable(2048);
md5[0] = 0;
md5String[0] = 0;
}
~BuildMD5ableBuffer()
{
delete stringTable;
}
void ReadSMC_ParseStart()
{
checksum = MD5();
}
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
{
stringTable->AddString(key);
stringTable->AddString(value);
return SMCResult_Continue;
}
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
{
stringTable->AddString(name);
return SMCResult_Continue;
}
void ReadSMC_ParseEnd(bool halted, bool failed)
{
if (halted || failed)
{
return;
}
void *data = stringTable->GetMemTable()->GetAddress(0);
if (data != NULL)
{
checksum.update((unsigned char *)data, stringTable->GetMemTable()->GetActualMemUsed());
}
checksum.finalize();
checksum.hex_digest(md5String);
checksum.raw_digest(md5);
stringTable->Reset();
}
unsigned char * GetMD5()
{
return md5;
}
unsigned char * GetMD5String()
{
return (unsigned char *)&md5String[0];
}
private:
MD5 checksum;
unsigned char md5[16];
char md5String[33];
BaseStringTable *stringTable;
};
#endif // _INCLUDE_GAMEDATAMD5_MAIN_H_
+485
View File
@@ -0,0 +1,485 @@
// MD5.CC - source code for the C++/object oriented translation and
// modification of MD5.
// Translation and modification (c) 1995 by Mordechai T. Abzug
// This translation/ modification is provided "as is," without express or
// implied warranty of any kind.
// The translator/ modifier does not claim (1) that MD5 will do what you think
// it does; (2) that this translation/ modification is accurate; or (3) that
// this software is "merchantible." (Language for this disclaimer partially
// copied from the disclaimer below).
/* based on:
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
MDDRIVER.C - test driver for MD2, MD4 and MD5
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5.h"
#include <assert.h>
#include <string.h>
// MD5 simple initialization method
MD5::MD5(){
init();
}
// MD5 block update operation. Continues an MD5 message-digest
// operation, processing another message block, and updating the
// context.
void MD5::update (uint1 *input, uint4 input_length) {
uint4 input_index, buffer_index;
uint4 buffer_space; // how much space is left in buffer
if (finalized){ // so we can't update!
/*cerr << "MD5::update: Can't update a finalized digest!" << endl;*/
return;
}
// Compute number of bytes mod 64
buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
// Update number of bits
if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
count[1]++;
count[1] += ((uint4)input_length >> 29);
buffer_space = 64 - buffer_index; // how much space is left in buffer
// Transform as many times as possible.
if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
// fill the rest of the buffer and transform
memcpy (buffer + buffer_index, input, buffer_space);
transform (buffer);
// now, transform each 64-byte piece of the input, bypassing the buffer
for (input_index = buffer_space; input_index + 63 < input_length;
input_index += 64)
transform (input+input_index);
buffer_index = 0; // so we can buffer remaining
}
else
input_index=0; // so we can buffer the whole input
// and here we do the buffering:
memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
}
// MD5 update for files.
// Like above, except that it works on files (and uses above as a primitive.)
void MD5::update(FILE *file){
unsigned char buffer[1024];
int len;
while ((len=fread(buffer, 1, 1024, file)))
update(buffer, len);
fclose (file);
}
// MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context.
void MD5::finalize (){
unsigned char bits[8];
unsigned int index, padLen;
static uint1 PADDING[64]={
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
if (finalized){
/* cerr << "MD5::finalize: Already finalized this digest!" << endl;*/
return;
}
// Save number of bits
encode (bits, count, 8);
// Pad out to 56 mod 64.
index = (uint4) ((count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
update (PADDING, padLen);
// Append length (before padding)
update (bits, 8);
// Store state in digest
encode (digest, state, 16);
// Zeroize sensitive information
memset (buffer, 0, sizeof(*buffer));
finalized=1;
}
MD5::MD5(FILE *file){
init(); // must be called be all constructors
update(file);
finalize ();
}
unsigned char *MD5::raw_digest(){
uint1 *s = new uint1[16];
if (!finalized){
/* cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
"finalized the digest!" <<endl;*/
return ( (unsigned char*) "");
}
memcpy(s, digest, 16);
return s;
}
unsigned char *MD5::raw_digest(unsigned char buffer[16])
{
if (!finalized)
{
return ( (unsigned char*) "");
}
memcpy(buffer, digest, 16);
return buffer;
}
char *MD5::hex_digest(){
int i;
char *s= new char[33];
if (!finalized){
/* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
"finalized the digest!" <<endl;*/
return "";
}
for (i=0; i<16; i++)
sprintf(s+i*2, "%02x", digest[i]);
s[32]='\0';
return s;
}
char *MD5::hex_digest(char buffer[33]){
int i;
if (!finalized)
{
/* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
"finalized the digest!" <<endl;*/
return "";
}
for (i=0; i<16; i++)
sprintf(buffer+i*2, "%02x", digest[i]);
buffer[32]='\0';
return buffer;
}
// PRIVATE METHODS:
void MD5::init(){
finalized=0; // we just started!
// Nothing counted, so count=0
count[0] = 0;
count[1] = 0;
// Load magic initialization constants.
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
}
// Constants for MD5Transform routine.
// Although we could use C++ style constants, defines are actually better,
// since they let us easily evade scope clashes.
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
// MD5 basic transformation. Transforms state based on block.
void MD5::transform (uint1 block[64]){
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
decode (x, block, 64);
assert(!finalized); // not just a user error, since the method is private
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
// Zeroize sensitive information.
memset ( (uint1 *) x, 0, sizeof(x));
}
// Encodes input (UINT4) into output (unsigned char). Assumes len is
// a multiple of 4.
void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (uint1) (input[i] & 0xff);
output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
}
}
// Decodes input (unsigned char) into output (UINT4). Assumes len is
// a multiple of 4.
void MD5::decode (uint4 *output, uint1 *input, uint4 len){
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
}
// Note: Replace "for loop" with standard memcpy if possible.
void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
// Note: Replace "for loop" with standard memset if possible.
void MD5::memset (uint1 *output, uint1 value, uint4 len){
unsigned int i;
for (i = 0; i < len; i++)
output[i] = value;
}
// ROTATE_LEFT rotates x left n bits.
inline unsigned int MD5::rotate_left (uint4 x, uint4 n){
return (x << n) | (x >> (32-n)) ;
}
// F, G, H and I are basic MD5 functions.
inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){
return (x & y) | (~x & z);
}
inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){
return (x & z) | (y & ~z);
}
inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){
return x ^ y ^ z;
}
inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){
return y ^ (x | ~z);
}
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){
a += F(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){
a += G(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){
a += H(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){
a += I(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
+106
View File
@@ -0,0 +1,106 @@
// MD5.CC - source code for the C++/object oriented translation and
// modification of MD5.
// Translation and modification (c) 1995 by Mordechai T. Abzug
// This translation/ modification is provided "as is," without express or
// implied warranty of any kind.
// The translator/ modifier does not claim (1) that MD5 will do what you think
// it does; (2) that this translation/ modification is accurate; or (3) that
// this software is "merchantible." (Language for this disclaimer partially
// copied from the disclaimer below).
/* based on:
MD5.H - header file for MD5C.C
MDDRIVER.C - test driver for MD2, MD4 and MD5
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include <stdio.h>
//#include <fstream.h>
//#include <iostream.h>
class MD5 {
public:
// methods for controlled operation:
MD5 (); // simple initializer
void update (unsigned char *input, unsigned int input_length);
void update (FILE *file);
void finalize ();
// constructors for special circumstances. All these constructors finalize
// the MD5 context.
MD5 (unsigned char *string); // digest string, finalize
MD5 (FILE *file); // digest file, close, finalize
// methods to acquire finalized result
unsigned char *raw_digest (); // digest as a 16-byte binary array
unsigned char *raw_digest(unsigned char buffer[16]);
char * hex_digest (); // digest as a 33-byte ascii-hex string
char * hex_digest (char buffer[33]); //same as above, passing buffer
private:
// first, some types:
typedef unsigned int uint4; // assumes integer is 4 words long
typedef unsigned short int uint2; // assumes short integer is 2 words long
typedef unsigned char uint1; // assumes char is 1 word long
// next, the private data:
uint4 state[4];
uint4 count[2]; // number of *bits*, mod 2^64
uint1 buffer[64]; // input buffer
uint1 digest[16];
uint1 finalized;
// last, the private methods, mostly static:
void init (); // called by all constructors
void transform (uint1 *buffer); // does the real update work. Note
// that length is implied to be 64.
static void encode (uint1 *dest, uint4 *src, uint4 length);
static void decode (uint4 *dest, uint1 *src, uint4 length);
static void memcpy (uint1 *dest, uint1 *src, uint4 length);
static void memset (uint1 *start, uint1 val, uint4 length);
static inline uint4 rotate_left (uint4 x, uint4 n);
static inline uint4 F (uint4 x, uint4 y, uint4 z);
static inline uint4 G (uint4 x, uint4 y, uint4 z);
static inline uint4 H (uint4 x, uint4 y, uint4 z);
static inline uint4 I (uint4 x, uint4 y, uint4 z);
static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac);
static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac);
static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac);
static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac);
};
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gamedatamd5", "gamedatamd5.vcproj", "{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.ActiveCfg = Debug|Win32
{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Debug|Win32.Build.0 = Debug|Win32
{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.ActiveCfg = Release|Win32
{E1C96598-E1AC-4928-8930-F8B6CD245B12}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+219
View File
@@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="gamedatamd5"
ProjectGUID="{E1C96598-E1AC-4928-8930-F8B6CD245B12}"
Keyword="Win32Proj"
TargetFrameworkVersion="0"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../public;../../../public/sourcepawn"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\main.h"
>
</File>
<File
RelativePath="..\md5.h"
>
</File>
<File
RelativePath="..\sm_memtable.h"
>
</File>
<File
RelativePath="..\TextParsers.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\main.cpp"
>
</File>
<File
RelativePath="..\md5.cpp"
>
</File>
<File
RelativePath="..\sm_memtable.cpp"
>
</File>
<File
RelativePath="..\TextParsers.cpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+112
View File
@@ -0,0 +1,112 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include <string.h>
#include <malloc.h>
#include "sm_memtable.h"
BaseMemTable::BaseMemTable(unsigned int init_size)
{
membase = (unsigned char *)malloc(init_size);
size = init_size;
tail = 0;
}
BaseMemTable::~BaseMemTable()
{
free(membase);
membase = NULL;
}
int BaseMemTable::CreateMem(unsigned int addsize, void **addr)
{
int idx = (int)tail;
while (tail + addsize >= size)
{
size *= 2;
membase = (unsigned char *)realloc(membase, size);
}
tail += addsize;
if (addr)
{
*addr = (void *)&membase[idx];
}
return idx;
}
void *BaseMemTable::GetAddress(int index)
{
if (index < 0 || (unsigned int)index >= tail)
{
return NULL;
}
return &membase[index];
}
void BaseMemTable::Reset()
{
tail = 0;
}
BaseStringTable::BaseStringTable(unsigned int init_size) : m_table(init_size)
{
}
BaseStringTable::~BaseStringTable()
{
}
int BaseStringTable::AddString(const char *string)
{
size_t len = strlen(string) + 1;
int idx;
char *addr;
idx = m_table.CreateMem(len, (void **)&addr);
strcpy(addr, string);
return idx;
}
/*const char *BaseStringTable::GetString(int str)
{
return (const char *)m_table.GetAddress(str);
}*/
void BaseStringTable::Reset()
{
m_table.Reset();
}
+114
View File
@@ -0,0 +1,114 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
#define _INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
class BaseMemTable
{
public:
BaseMemTable(unsigned int init_size);
~BaseMemTable();
public:
/**
* Allocates 'size' bytes of memory.
* Optionally outputs the address through 'addr'.
* Returns an index >= 0 on success, < 0 on failure.
*/
int CreateMem(unsigned int size, void **addr);
/**
* Given an index into the memory table, returns its address.
* Returns NULL if invalid.
*/
void *GetAddress(int index);
/**
* Scraps the memory table. For caching purposes, the memory
* is not freed, however subsequent calls to CreateMem() will
* begin at the first index again.
*/
void Reset();
inline unsigned int GetMemUsage()
{
return size;
}
inline unsigned int GetActualMemUsed()
{
return tail;
}
private:
unsigned char *membase;
unsigned int size;
unsigned int tail;
};
class BaseStringTable
{
public:
BaseStringTable(unsigned int init_size);
~BaseStringTable();
public:
/**
* Adds a string to the string table and returns its index.
*/
int AddString(const char *string);
/**
* Given an index into the string table, returns the associated string.
*/
inline const char *GetString(int str)
{
return (const char *)m_table.GetAddress(str);
}
/**
* Scraps the string table. For caching purposes, the memory
* is not freed, however subsequent calls to AddString() will
* begin at the first index again.
*/
void Reset();
/**
* Returns the parent BaseMemTable that this string table uses.
*/
inline BaseMemTable *GetMemTable()
{
return &m_table;
}
private:
BaseMemTable m_table;
};
#endif //_INCLUDE_SOURCEMOD_CORE_STRINGTABLE_H_
File diff suppressed because it is too large Load Diff
+174
View File
@@ -0,0 +1,174 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace incparser
{
class ParseWriter
{
private int level;
private StringBuilder data;
public ArrayList enumList = new ArrayList();
public ArrayList defineList = new ArrayList();
public ArrayList enumTypeList = new ArrayList();
public ArrayList forwardList = new ArrayList();
public ArrayList nativeList = new ArrayList();
public ArrayList stockList = new ArrayList();
public ArrayList funcenumList = new ArrayList();
public ArrayList functagList = new ArrayList();
public ArrayList structList = new ArrayList();
public int Level
{
get
{
return level;
}
}
public string Contents
{
get
{
return data.ToString();
}
}
public void Reset()
{
level = 0;
data = new StringBuilder();
}
public ParseWriter()
{
level = 0;
data = new StringBuilder();
}
public void BeginSection(string name)
{
WriteLine("\"" + PrepString(name) + "\"");
WriteLine("{");
level++;
}
public void WritePair(string key, string value)
{
WriteLine("\"" + PrepString(key) + "\"\t\t\"" + PrepString(value) + "\"");
}
public void EndSection()
{
if (--level < 0)
{
throw new System.Exception("Writer nesting level went out of bounds");
}
WriteLine("}");
}
public void WriteFiles(string template, string outputfile)
{
StreamReader sr = null;
try
{
sr = File.OpenText(template);
}
catch (Exception e)
{
Console.WriteLine("Failed to open template file: " + e.Message);
return;
}
string contents = sr.ReadToEnd();
string replace = ToOutputString(defineList);
contents = contents.Replace("$defines", replace);
replace = ToOutputString(enumList);
contents = contents.Replace("$enums", replace);
replace = ToOutputString(enumTypeList);
contents = contents.Replace("$enumtypes", replace);
replace = ToOutputString(forwardList);
contents = contents.Replace("$forwards", replace);
replace = ToOutputString(nativeList);
contents = contents.Replace("$natives", replace);
replace = ToOutputString(stockList);
contents = contents.Replace("$stocks", replace);
replace = ToOutputString(funcenumList);
contents = contents.Replace("$funcenums", replace);
replace = ToOutputString(functagList);
contents = contents.Replace("$functags", replace);
replace = ToOutputString(structList);
contents = contents.Replace("$structs", replace);
StreamWriter sw;
sw = File.CreateText(outputfile);
sw.Write(contents);
sr.Close();
sw.Close();
}
private string ToOutputString(ArrayList a)
{
string defines = "";
int count = 0;
foreach (object o in a)
{
defines += o;
defines += " ";
count += o.ToString().Length;
if (count > 180)
{
defines += "\r\n";
count = 0;
}
}
return defines;
}
private void WriteLine(string line)
{
Tabinate();
data.Append(line + "\n");
}
private void Tabinate()
{
for (int i = 0; i < level; i++)
{
data.Append("\t");
}
}
private string PrepString(string text)
{
/* Escape all escaped newlines (so they can be unescaped later) */
text = text.Replace("\\n", "\\\\n");
/* Escape all literal newlines */
text = text.Replace("\n", "\\n");
text = text.Replace("\r", "");
/* Remove escaped quotations */
text = text.Replace("\\\"", "\"");
/* Replace all quotations with escaped ones now */
text = text.Replace("\"", "\\\"");
return text;
}
}
}
+183
View File
@@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace incparser
{
class Program
{
static void Main(string[] args)
{
Environment.Exit(SubMain(args));
}
static int SubMain(string[] args)
{
string directory = ".";
string template = "template.txt";
string outputfile = "output.txt";
string file = null;
if (args.Length == 0 || (args.Length == 1 && args[0] == "-h"))
{
PrintHelp();
return 0;
}
for (int i=0; i<args.Length-1; i++)
{
if (args[i] == "-d")
{
directory = args[i + 1];
}
if (args[i] == "-t")
{
template = args[i + 1];
}
if (args[i] == "-o")
{
outputfile = args[i + 1];
}
if (args[i] == "-f")
{
file = args[i + 1];
}
if (args[i] == "-h")
{
if (args[i + 1] == "template")
{
PrintTemplateHelp();
return 0;
}
PrintHelp();
return 0;
}
}
IncParser inc = null;
if (file == null)
{
DirectoryInfo di = new DirectoryInfo(directory);
FileInfo[] rgFiles = di.GetFiles("*.inc");
ParseWriter pwr = new ParseWriter();
foreach (FileInfo fi in rgFiles)
{
pwr.Reset();
Console.Write("Parsing file: " + fi.ToString() + "... ");
try
{
inc = new IncParser(fi.FullName);
}
catch (ParseException e)
{
Console.WriteLine("Initial browsing failed: " + e.Message);
continue;
}
catch (System.Exception e)
{
Console.WriteLine("Failed to read file: " + e.Message);
continue;
}
try
{
inc.Parse(pwr);
}
catch (System.Exception e)
{
Console.WriteLine("Error parsing file (line " + inc.GetLineNumber() + "): " + e.Message);
continue;
}
if (pwr.Level != 0)
{
Console.WriteLine("Fatal parse error detected; unable to complete output.");
continue;
}
Console.WriteLine("Complete!");
}
pwr.WriteFiles(template, outputfile);
Console.WriteLine("Parsing Complete!");
return 0;
}
try
{
inc = new IncParser(file);
}
catch (ParseException e)
{
Console.WriteLine("Initial browsing failed: " + e.Message);
return 1;
}
catch (System.Exception e)
{
Console.WriteLine("Failed to read file: " + e.Message);
return 1;
}
ParseWriter pw = new ParseWriter();
try
{
inc.Parse(pw);
}
catch (System.Exception e)
{
Console.WriteLine("Error parsing file (line " + inc.GetLineNumber() + "): " + e.Message);
return 1;
}
if (pw.Level != 0)
{
Console.WriteLine("Fatal parse error detected; unable to complete output.");
return 1;
}
Console.Write(pw.Contents);
Console.Write("\n");
return 0;
}
static void PrintHelp()
{
Console.WriteLine("SourcePawn include file parser by BAILOPAN (edited by pRED*)");
Console.Write("\n");
Console.WriteLine("This can parse a single file into SMC configuration format or an entire directory into a template file if -f is not specified (current directory is used if -d is not specified)");
Console.Write("\n");
Console.WriteLine("Parameters:");
Console.Write("\n");
Console.WriteLine("-f <filename> - Specify an input file to be used");
Console.WriteLine("-d <path> - Specify a directory to parse (only *.inc files are used)");
Console.WriteLine("-t <filename> - Specify a template file to be used");
Console.WriteLine("-o <filename> - Specify an output file to be used");
Console.WriteLine("-h - Display this help");
Console.WriteLine("-h template - Displays help about templates");
}
static void PrintTemplateHelp()
{
Console.WriteLine("Template File Help:");
Console.WriteLine("The inc parser can read a template file and replace variables with the outputs of it's parse and write into the output file");
Console.Write("\n");
Console.WriteLine("Variables:");
Console.Write("\n");
Console.WriteLine("$defines $enums $enumtypes $forwards $natives $stocks $funcenums $functags $structs");
}
}
}
@@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("incparser")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("AlliedModders")]
[assembly: AssemblyProduct("incparser")]
[assembly: AssemblyCopyright("Copyright © AlliedModders 2007")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("81138f67-d686-415d-b9e2-0fca86c29a22")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+55
View File
@@ -0,0 +1,55 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{064EA9DC-51DC-4EE5-843B-0E3F7069635E}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>incparser</RootNamespace>
<AssemblyName>incparser</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="IncParser.cs" />
<Compile Include="ParseWriter.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C# Express 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "incparser", "incparser.csproj", "{064EA9DC-51DC-4EE5-843B-0E3F7069635E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{064EA9DC-51DC-4EE5-843B-0E3F7069635E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{064EA9DC-51DC-4EE5-843B-0E3F7069635E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{064EA9DC-51DC-4EE5-843B-0E3F7069635E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{064EA9DC-51DC-4EE5-843B-0E3F7069635E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+37
View File
@@ -0,0 +1,37 @@
#ifndef _INCLUDE_INSTALLER_CRIT_SECT_H_
#define _INCLUDE_INSTALLER_CRIT_SECT_H_
#include "platform_headers.h"
class CCriticalSection
{
public:
CCriticalSection()
{
InitializeCriticalSection(&m_crit);
}
~CCriticalSection()
{
DeleteCriticalSection(&m_crit);
}
void Enter()
{
EnterCriticalSection(&m_crit);
}
bool TryEnter()
{
if (TryEnterCriticalSection(&m_crit))
{
return true;
}
return false;
}
void Leave()
{
LeaveCriticalSection(&m_crit);
}
private:
CRITICAL_SECTION m_crit;
};
#endif //_INCLUDE_INSTALLER_CRIT_SECT_H_
+151
View File
@@ -0,0 +1,151 @@
#include "CFileList.h"
#include "InstallerUtil.h"
using namespace std;
CFileList::CFileList(const TCHAR *name) : m_TotalSize(0), m_RecursiveSize(0),
m_bGotRecursiveSize(false)
{
UTIL_Format(m_FolderName, sizeof(m_FolderName) / sizeof(TCHAR), _T("%s"), name);
}
CFileList::~CFileList()
{
list<CFileList *>::iterator iter;
for (iter = m_folder_list.begin();
iter != m_folder_list.end();
iter++)
{
delete (*iter);
}
}
const TCHAR *CFileList::GetFolderName()
{
return m_FolderName;
}
void CFileList::AddFolder(CFileList *pFileList)
{
m_folder_list.push_back(pFileList);
}
void CFileList::AddFile(const TCHAR *name, unsigned __int64 size)
{
CFileListEntry entry;
UTIL_Format(entry.file, sizeof(entry.file) / sizeof(TCHAR), _T("%s"), name);
entry.size = size;
m_file_list.push_back(entry);
m_TotalSize += size;
}
unsigned __int64 CFileList::GetRecursiveSize()
{
if (m_bGotRecursiveSize)
{
return m_RecursiveSize;
}
m_RecursiveSize = m_TotalSize;
list<CFileList *>::iterator iter;
for (iter = m_folder_list.begin(); iter != m_folder_list.end(); iter++)
{
m_RecursiveSize += (*iter)->GetRecursiveSize();
}
m_bGotRecursiveSize = true;
return m_RecursiveSize;
}
const TCHAR *CFileList::PeekCurrentFile()
{
if (m_file_list.empty())
{
return NULL;
}
return m_file_list.begin()->file;
}
void CFileList::PopCurrentFile()
{
m_file_list.erase(m_file_list.begin());
}
CFileList *CFileList::PeekCurrentFolder()
{
if (m_folder_list.empty())
{
return NULL;
}
return *(m_folder_list.begin());
}
void CFileList::PopCurrentFolder()
{
m_folder_list.erase(m_folder_list.begin());
}
void RecursiveBuildFileList(CFileList *file_list, const TCHAR *current_folder)
{
HANDLE hFind;
WIN32_FIND_DATA fd;
TCHAR path[MAX_PATH];
UTIL_PathFormat(path, sizeof(path) / sizeof(TCHAR), _T("%s\\*.*"), current_folder);
if ((hFind = FindFirstFile(path, &fd)) == INVALID_HANDLE_VALUE)
{
return;
}
do
{
if (tstrcasecmp(fd.cFileName, _T(".")) == 0
|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
{
continue;
}
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
{
CFileList *pSubList = new CFileList(fd.cFileName);
UTIL_PathFormat(path,
sizeof(path) / sizeof(TCHAR),
_T("%s\\%s"),
current_folder,
fd.cFileName);
RecursiveBuildFileList(pSubList, path);
file_list->AddFolder(pSubList);
}
else
{
LARGE_INTEGER li;
li.LowPart = fd.nFileSizeLow;
li.HighPart = fd.nFileSizeHigh;
file_list->AddFile(fd.cFileName, li.QuadPart);
}
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
}
CFileList *CFileList::BuildFileList(const TCHAR *name, const TCHAR *root_folder)
{
CFileList *pFileList = new CFileList(name);
RecursiveBuildFileList(pFileList, root_folder);
return pFileList;
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef _INCLUDE_FOLDER_LIST_H_
#define _INCLUDE_FOLDER_LIST_H_
#include "platform_headers.h"
#include <list>
#include <vector>
struct CFileListEntry
{
TCHAR file[MAX_PATH];
unsigned __int64 size;
};
class CFileList
{
public:
CFileList(const TCHAR *name);
~CFileList();
public:
CFileList *PeekCurrentFolder();
void PopCurrentFolder();
const TCHAR *PeekCurrentFile();
void PopCurrentFile();
const TCHAR *GetFolderName();
public:
void AddFolder(CFileList *pFileList);
void AddFile(const TCHAR *name, unsigned __int64 size);
unsigned __int64 GetRecursiveSize();
public:
static CFileList *BuildFileList(const TCHAR *name, const TCHAR *root_folder);
private:
std::list<CFileList *> m_folder_list;
std::list<CFileListEntry> m_file_list;
TCHAR m_FolderName[MAX_PATH];
unsigned __int64 m_TotalSize;
unsigned __int64 m_RecursiveSize;
bool m_bGotRecursiveSize;
};
#endif //_INCLUDE_FOLDER_LIST_H_
+235
View File
@@ -0,0 +1,235 @@
#include "InstallerMain.h"
#include "InstallerUtil.h"
#include "ChooseMethod.h"
#include "Welcome.h"
#include "GamesList.h"
#include "SelectGame.h"
#include "PerformInstall.h"
#include "LocalCopyMethod.h"
game_group_t *g_game_group = NULL;
unsigned int method_chosen = 0;
TCHAR method_path[MAX_PATH];
bool SelectFolder(HWND hOwner)
{
BROWSEINFO info;
LPITEMIDLIST pidlist;
TCHAR path[MAX_PATH];
if (FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
{
return false;
}
info.hwndOwner = hOwner;
info.pidlRoot = NULL;
info.pszDisplayName = path;
info.lpszTitle = _T("Select a game/mod folder");
info.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
info.lpfn = NULL;
info.lParam = 0;
info.iImage = 0;
if ((pidlist = SHBrowseForFolder(&info)) == NULL)
{
CoUninitialize();
return false;
}
/* This hellish code is from MSDN and translate shortcuts to real targets.
* God almighty, I wish Window used real symlinks.
*/
bool acquire_success = false;
bool is_link = false;
IShellFolder *psf = NULL;
LPCITEMIDLIST new_item_list;
HRESULT hr;
hr = SHBindToParent(pidlist, IID_IShellFolder, (void **)&psf, &new_item_list);
if (SUCCEEDED(hr))
{
IShellLink *psl = NULL;
hr = psf->GetUIObjectOf(hOwner, 1, &new_item_list, IID_IShellLink, NULL, (void **)&psl);
if (SUCCEEDED(hr))
{
LPITEMIDLIST new_item_list;
hr = psl->GetIDList(&new_item_list);
if (SUCCEEDED(hr))
{
is_link = true;
hr = SHGetPathFromIDList(new_item_list, method_path);
if (SUCCEEDED(hr))
{
acquire_success = true;
}
CoTaskMemFree(new_item_list);
}
psl->Release();
}
psf->Release();
}
if (!acquire_success && !is_link)
{
hr = SHGetPathFromIDList(pidlist, method_path);
if (SUCCEEDED(hr))
{
acquire_success = true;
}
}
/* That was awful. shoo, shoo, COM */
CoTaskMemFree(pidlist);
CoUninitialize();
return acquire_success;
}
INT_PTR CALLBACK ChooseMethodHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
if (LOWORD(wParam) == ID_METHOD_BACK)
{
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, (INT_PTR)DisplayWelcome);
return (INT_PTR)TRUE;
}
else if (LOWORD(wParam) == ID_METHOD_EXIT
|| LOWORD(wParam) == ID_CLOSE)
{
return AskToExit(hDlg);
}
else if (LOWORD(wParam) == IDC_METHOD_DED_SERVER
|| LOWORD(wParam) == IDC_METHOD_ALONE_SERVER
|| LOWORD(wParam) == IDC_METHOD_LISTEN_SERVER
|| LOWORD(wParam) == IDC_METHOD_UPLOAD_FTP
|| LOWORD(wParam) == IDC_METHOD_CUSTOM_FOLDER)
{
method_chosen = LOWORD(wParam);
HWND button = GetDlgItem(hDlg, ID_METHOD_NEXT);
EnableWindow(button, TRUE);
break;
}
else if (LOWORD(wParam) == ID_METHOD_NEXT)
{
unsigned int game_type = 0;
switch (method_chosen)
{
case IDC_METHOD_DED_SERVER:
{
game_type = GAMES_DEDICATED;
break;
}
case IDC_METHOD_ALONE_SERVER:
{
game_type = GAMES_STANDALONE;
break;
}
case IDC_METHOD_LISTEN_SERVER:
{
game_type = GAMES_LISTEN;
break;
}
case IDC_METHOD_UPLOAD_FTP:
{
break;
}
case IDC_METHOD_CUSTOM_FOLDER:
{
int val;
if (!SelectFolder(hDlg))
{
break;
}
val = IsValidFolder(method_path);
if (val != GAMEINFO_IS_USABLE)
{
DisplayBadFolderDialog(hDlg, val);
break;
}
g_LocalCopier.SetOutputPath(method_path);
SetInstallMethod(&g_LocalCopier);
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, (INT_PTR)DisplayPerformInstall);
}
}
if (game_type != 0)
{
g_game_group = NULL;
BuildGameDB();
if (game_type == GAMES_DEDICATED)
{
g_game_group = &g_games.dedicated;
}
else if (game_type == GAMES_LISTEN)
{
g_game_group = &g_games.listen;
}
else if (game_type == GAMES_STANDALONE)
{
g_game_group = &g_games.standalone;
}
if (g_game_group == NULL)
{
return (INT_PTR)TRUE;
}
if (g_game_group->list_count == 0)
{
DisplayBadGamesDialog(hDlg, g_game_group->error_code);
return (INT_PTR)TRUE;
}
/* If we got a valid games list, we can display the next
* dialog box.
*/
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, (INT_PTR)DisplaySelectGame);
return (INT_PTR)TRUE;
}
}
break;
}
case WM_INITDIALOG:
{
SetToGlobalPosition(hDlg);
return (INT_PTR)TRUE;
}
}
return (INT_PTR)FALSE;
}
void *DisplayChooseMethod(HWND hWnd)
{
INT_PTR val;
if ((val = DialogBox(
g_hInstance,
MAKEINTRESOURCE(IDD_CHOOSE_METHOD),
hWnd,
ChooseMethodHandler)) == -1)
{
return NULL;
}
return (void *)val;
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef _INCLUDE_INSTALLER_CHOOSE_METHOD_H_
#define _INCLUDE_INSTALLER_CHOOSE_METHOD_H_
#include "InstallerMain.h"
#include "GamesList.h"
void *DisplayChooseMethod(HWND hWnd);
extern game_group_t *g_game_group;
#endif //_INCLUDE_INSTALLER_CHOOSE_METHOD_H_
+574
View File
@@ -0,0 +1,574 @@
#include "GamesList.h"
#include "InstallerUtil.h"
#include "InstallerMain.h"
#include <stdio.h>
game_database_t g_games =
{
NULL, 0,
{NULL, 0, GAME_LIST_NO_GAMES},
{NULL, 0, GAME_LIST_NO_GAMES},
{NULL, 0, GAME_LIST_NO_GAMES}
};
valve_game_t valve_game_list[] =
{
{_T("counter-strike source"), _T("cstrike"), SOURCE_ENGINE_2004},
{_T("day of defeat source"), _T("dod"), SOURCE_ENGINE_2004},
{_T("half-life 2 deathmatch"), _T("hl2mp"), SOURCE_ENGINE_2004},
{_T("half-life deathmatch source"), _T("hl1mp"), SOURCE_ENGINE_2004},
{_T("team fortress 2"), _T("tf"), SOURCE_ENGINE_2007},
{NULL, NULL, 0},
};
valve_game_t valve_server_list[] =
{
{_T("source dedicated server"), NULL, SOURCE_ENGINE_2004},
{_T("source 2007 dedicated server"), NULL, SOURCE_ENGINE_2007},
{NULL, NULL, 0},
};
int IsValidFolder(const TCHAR *path)
{
DWORD attr;
TCHAR gameinfo_file[MAX_PATH];
UTIL_PathFormat(gameinfo_file, sizeof(gameinfo_file), _T("%s\\gameinfo.txt"), path);
if ((attr = GetFileAttributes(gameinfo_file)) == INVALID_FILE_ATTRIBUTES)
{
return GAMEINFO_DOES_NOT_EXIST;
}
if ((attr & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY)
{
return GAMEINFO_IS_READ_ONLY;
}
if ((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
{
return GAMEINFO_DOES_NOT_EXIST;
}
return GAMEINFO_IS_USABLE;
}
void DisplayBadFolderDialog(HWND hDlg, int reason)
{
TCHAR message_string[255];
UINT resource;
if (reason == GAMEINFO_DOES_NOT_EXIST)
{
resource = IDS_NO_GAMEINFO;
}
else if (reason == GAMEINFO_IS_READ_ONLY)
{
resource = IDS_READONLY_GAMEINFO;
}
else
{
return;
}
if (LoadString(g_hInstance,
resource,
message_string,
sizeof(message_string) / sizeof(TCHAR)
) == 0)
{
return;
}
MessageBox(hDlg,
message_string,
_T("SourceMod Installer"),
MB_OK|MB_ICONWARNING);
}
game_list_t *MakeGameList(const TCHAR *name)
{
game_list_t *gl = (game_list_t *)malloc(sizeof(game_list_t));
UTIL_Format(gl->root_name,
sizeof(gl->root_name) / sizeof(TCHAR),
_T("%s"),
name);
gl->game_count = 0;
gl->games = NULL;
return gl;
}
void AttachGameListToGroup(game_group_t *group, game_list_t *gl)
{
if (group->lists == NULL)
{
group->lists = (game_list_t **)malloc(sizeof(game_list_t *));
}
else
{
group->lists = (game_list_t **)realloc(group->lists,
sizeof(game_list_t *) * (group->list_count + 1));
}
group->lists[group->list_count] = gl;
group->list_count++;
}
void AttachModToGameList(game_list_t *gl, unsigned int mod_id)
{
if (gl->games == NULL)
{
gl->games = (unsigned int *)malloc(sizeof(unsigned int));
}
else
{
gl->games = (unsigned int *)realloc(gl->games,
sizeof(unsigned int) * (gl->game_count + 1));
}
gl->games[gl->game_count] = mod_id;
gl->game_count++;
}
unsigned int AddModToList(game_database_t *db, const game_info_t *mod_info)
{
/* Check if a matching game already exists */
for (unsigned int i = 0; i < db->game_count; i++)
{
if (tstrcasecmp(mod_info->game_path, db->game_list[i].game_path) == 0)
{
return i;
}
}
if (db->game_list == NULL)
{
db->game_list = (game_info_t *)malloc(sizeof(game_info_t));
}
else
{
db->game_list = (game_info_t *)realloc(db->game_list,
sizeof(game_info_t) * (db->game_count + 1));
}
memcpy(&db->game_list[db->game_count], mod_info, sizeof(game_info_t));
db->game_count++;
return db->game_count - 1;
}
bool TryToAddMod(const TCHAR *path, int eng_type, game_database_t *db, unsigned int *id)
{
FILE *fp;
TCHAR gameinfo_path[MAX_PATH];
UTIL_PathFormat(gameinfo_path,
sizeof(gameinfo_path),
_T("%s\\gameinfo.txt"),
path);
if ((fp = _tfopen(gameinfo_path, _T("rt"))) == NULL)
{
return false;
}
int pos;
char buffer[512];
char key[256], value[256];
while (!feof(fp) && fgets(buffer, sizeof(buffer), fp) != NULL)
{
if ((pos = BreakStringA(buffer, key, sizeof(key))) == -1)
{
continue;
}
if ((pos = BreakStringA(&buffer[pos], value, sizeof(value))) == -1)
{
continue;
}
if (strcmp(key, "game") == 0)
{
game_info_t mod;
unsigned int got_id;
AnsiToUnicode(value, mod.name, sizeof(mod.name));
UTIL_Format(mod.game_path, sizeof(mod.game_path), _T("%s"), path);
mod.source_engine = eng_type;
got_id = AddModToList(db, &mod);
if (id != NULL)
{
*id = got_id;
}
fclose(fp);
return true;
}
}
fclose(fp);
return false;
}
void AddModsFromFolder(const TCHAR *path,
int eng_type,
game_database_t *db,
game_list_t *gl)
{
HANDLE hFind;
WIN32_FIND_DATA fd;
TCHAR temp_path[MAX_PATH];
TCHAR search_path[MAX_PATH];
unsigned int mod_id;
UTIL_Format(search_path,
sizeof(search_path),
_T("%s\\*.*"),
path);
if ((hFind = FindFirstFile(search_path, &fd)) == INVALID_HANDLE_VALUE)
{
return;
}
do
{
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
{
continue;
}
if (tstrcasecmp(fd.cFileName, _T(".")) == 0
|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
{
continue;
}
UTIL_PathFormat(temp_path,
sizeof(temp_path),
_T("%s\\%s"),
path,
fd.cFileName);
if (TryToAddMod(temp_path, eng_type, db, &mod_id))
{
AttachModToGameList(gl, mod_id);
}
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
}
void GetSteamGames(game_database_t *db)
{
HKEY hkPath;
DWORD dwLen, dwType;
HANDLE hFind;
WIN32_FIND_DATA fd;
TCHAR temp_path[MAX_PATH];
TCHAR steam_path[MAX_PATH];
TCHAR steamapps_path[MAX_PATH];
if (RegOpenKeyEx(HKEY_CURRENT_USER,
_T("Software\\Valve\\Steam"),
0,
KEY_READ,
&hkPath) != ERROR_SUCCESS)
{
db->listen.error_code = GAME_LIST_CANT_READ;
db->dedicated.error_code = GAME_LIST_CANT_READ;
return;
}
dwLen = sizeof(steam_path) / sizeof(TCHAR);
if (RegQueryValueEx(hkPath,
_T("SteamPath"),
NULL,
&dwType,
(LPBYTE)steam_path,
&dwLen) != ERROR_SUCCESS)
{
RegCloseKey(hkPath);
db->listen.error_code = GAME_LIST_CANT_READ;
db->dedicated.error_code = GAME_LIST_CANT_READ;
return;
}
UTIL_PathFormat(steamapps_path,
sizeof(steamapps_path) / sizeof(TCHAR),
_T("%s\\steamapps\\*.*"),
steam_path);
if ((hFind = FindFirstFile(steamapps_path, &fd)) == INVALID_HANDLE_VALUE)
{
RegCloseKey(hkPath);
db->listen.error_code = GAME_LIST_CANT_READ;
db->dedicated.error_code = GAME_LIST_CANT_READ;
return;
}
do
{
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
{
continue;
}
if (tstrcasecmp(fd.cFileName, _T(".")) == 0
|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
{
continue;
}
/* If we get a folder called "SourceMods," look for third party mods */
if (tstrcasecmp(fd.cFileName, _T("SourceMods")) == 0)
{
game_list_t *gl = MakeGameList(_T("Third-Party Games"));
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\steamapps\\%s"),
steam_path,
fd.cFileName);
AddModsFromFolder(temp_path, SOURCE_ENGINE_UNKNOWN, db, gl);
if (gl->game_count)
{
AttachGameListToGroup(&db->listen, gl);
}
else
{
free(gl);
}
}
else
{
/* Look for listenserver games */
game_list_t *gl = MakeGameList(fd.cFileName);
for (unsigned int i = 0; valve_game_list[i].folder != NULL; i++)
{
unsigned int mod_id;
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\steamapps\\%s\\%s\\%s"),
steam_path,
fd.cFileName,
valve_game_list[i].folder,
valve_game_list[i].subfolder);
if (TryToAddMod(temp_path, valve_game_list[i].eng_type, db, &mod_id))
{
AttachModToGameList(gl, mod_id);
}
}
if (gl->game_count)
{
AttachGameListToGroup(&db->listen, gl);
}
else
{
free(gl);
}
/* Look for dedicated games */
gl = MakeGameList(fd.cFileName);
for (unsigned int i = 0; valve_server_list[i].folder != NULL; i++)
{
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\steamapps\\%s\\%s"),
steam_path,
fd.cFileName,
valve_server_list[i].folder);
AddModsFromFolder(temp_path, valve_server_list[i].eng_type, db, gl);
}
if (gl->game_count)
{
AttachGameListToGroup(&db->dedicated, gl);
}
else
{
free(gl);
}
}
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
RegCloseKey(hkPath);
}
void GetStandaloneGames(game_database_t *db)
{
HKEY hkPath;
DWORD dwLen, dwType, dwAttr;
TCHAR temp_path[MAX_PATH];
TCHAR hlds_path[MAX_PATH];
game_list_t *games_standalone;
if (RegOpenKeyEx(HKEY_CURRENT_USER,
_T("Software\\Valve\\HLServer"),
0,
KEY_READ,
&hkPath) != ERROR_SUCCESS)
{
db->standalone.error_code = GAME_LIST_CANT_READ;
return;
}
dwLen = sizeof(hlds_path) / sizeof(TCHAR);
if (RegQueryValueEx(hkPath,
_T("InstallPath"),
NULL,
&dwType,
(LPBYTE)hlds_path,
&dwLen) != ERROR_SUCCESS)
{
RegCloseKey(hkPath);
db->standalone.error_code = GAME_LIST_CANT_READ;
return;
}
/* Make sure there is a "srcds.exe" file */
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\srcds.exe"),
hlds_path);
dwAttr = GetFileAttributes(temp_path);
if (dwAttr == INVALID_FILE_ATTRIBUTES)
{
db->standalone.error_code = GAME_LIST_HALFLIFE1;
return;
}
games_standalone = MakeGameList(_T("Standalone"));
/* If there is an "orangebox" sub folder, we can make a better guess
* at the engine state.
*/
UTIL_PathFormat(temp_path,
sizeof(temp_path) / sizeof(TCHAR),
_T("%s\\orangebox"),
hlds_path);
dwAttr = GetFileAttributes(temp_path);
if (dwAttr != INVALID_FILE_ATTRIBUTES
&& ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
{
AddModsFromFolder(temp_path, SOURCE_ENGINE_2007, db, games_standalone);
}
/* Add everything from the server */
AddModsFromFolder(hlds_path, SOURCE_ENGINE_2004, db, games_standalone);
if (games_standalone->game_count)
{
AttachGameListToGroup(&db->standalone, games_standalone);
}
else
{
free(games_standalone);
}
RegCloseKey(hkPath);
}
void DisplayBadGamesDialog(HWND hWnd, int reason)
{
TCHAR message[256];
UINT idc = 0;
if (reason == GAME_LIST_CANT_READ)
{
idc = IDS_GAME_FAIL_READ;
}
else if (reason == GAME_LIST_HALFLIFE1)
{
idc = IDS_GAME_FAIL_HL1;
}
else if (reason == GAME_LIST_NO_GAMES)
{
idc = IDS_GAME_FAIL_NONE;
}
else
{
return;
}
if (LoadString(g_hInstance,
idc,
message,
sizeof(message) / sizeof(TCHAR)) == 0)
{
return;
}
MessageBox(hWnd,
message,
_T("SourceMod Installer"),
MB_OK|MB_ICONWARNING);
}
int _ModIdCompare(const void *item1, const void *item2)
{
unsigned int mod_id1 = *(unsigned int *)item1;
unsigned int mod_id2 = *(unsigned int *)item2;
return tstrcasecmp(g_games.game_list[mod_id1].name, g_games.game_list[mod_id2].name);
}
int _GroupCompare(const void *item1, const void *item2)
{
game_list_t *g1 = *(game_list_t **)item1;
game_list_t *g2 = *(game_list_t **)item2;
return tstrcasecmp(g1->root_name, g2->root_name);
}
void SortGameGroup(game_group_t *group)
{
qsort(group->lists, group->list_count, sizeof(game_list_t *), _GroupCompare);
for (unsigned int i = 0; i < group->list_count; i++)
{
qsort(group->lists[i]->games,
group->lists[i]->game_count,
sizeof(unsigned int),
_ModIdCompare);
}
}
void BuildGameDB()
{
ReleaseGameDB();
GetStandaloneGames(&g_games);
GetSteamGames(&g_games);
SortGameGroup(&g_games.dedicated);
SortGameGroup(&g_games.listen);
SortGameGroup(&g_games.standalone);
}
void ReleaseGameGroup(game_group_t *group)
{
for (unsigned int i = 0; i < group->list_count; i++)
{
free(group->lists[i]->games);
free(group->lists[i]);
}
free(group->lists);
}
void ReleaseGameDB()
{
ReleaseGameGroup(&g_games.dedicated);
ReleaseGameGroup(&g_games.listen);
ReleaseGameGroup(&g_games.standalone);
free(g_games.game_list);
memset(&g_games, 0, sizeof(g_games));
}
+72
View File
@@ -0,0 +1,72 @@
#ifndef _INCLUDE_INSTALLER_GAMES_LIST_H_
#define _INCLUDE_INSTALLER_GAMES_LIST_H_
#include "platform_headers.h"
#define GAMEINFO_IS_USABLE 0
#define GAMEINFO_DOES_NOT_EXIST 1
#define GAMEINFO_IS_READ_ONLY 2
#define GAME_LIST_HALFLIFE1 -2
#define GAME_LIST_CANT_READ -1
#define GAME_LIST_NO_GAMES 0
#define GAMES_DEDICATED 1
#define GAMES_LISTEN 2
#define GAMES_STANDALONE 3
#define SOURCE_ENGINE_UNKNOWN 0
#define SOURCE_ENGINE_2004 1
#define SOURCE_ENGINE_2007 2
struct valve_game_t
{
const TCHAR *folder;
const TCHAR *subfolder;
int eng_type;
};
/* One game */
struct game_info_t
{
TCHAR name[128];
TCHAR game_path[MAX_PATH];
int source_engine;
};
/* A list of games under one "account" */
struct game_list_t
{
TCHAR root_name[128];
unsigned int *games;
unsigned int game_count;
};
/* A list of accounts */
struct game_group_t
{
game_list_t **lists;
unsigned int list_count;
int error_code;
};
/* All games on the system */
struct game_database_t
{
game_info_t *game_list;
unsigned int game_count;
game_group_t dedicated;
game_group_t listen;
game_group_t standalone;
};
int IsValidFolder(const TCHAR *path);
void DisplayBadFolderDialog(HWND hWnd, int reason);
void BuildGameDB();
void ReleaseGameDB();
void DisplayBadGamesDialog(HWND hWnd, int reason);
extern game_database_t g_games;
#endif //_INCLUDE_INSTALLER_GAMES_LIST_H_
+25
View File
@@ -0,0 +1,25 @@
#ifndef _INCLUDE_INSTALLER_COPY_METHOD_H_
#define _INCLUDE_INSTALLER_COPY_METHOD_H_
#include "platform_headers.h"
class ICopyProgress
{
public:
virtual void StartingNewFile(const TCHAR *filename) =0;
virtual void UpdateProgress(size_t bytes, size_t total_bytes) =0;
virtual void FileDone(size_t file_size) =0;
};
class ICopyMethod
{
public:
virtual bool CheckForExistingInstall() =0;
virtual void TrackProgress(ICopyProgress *pProgress) =0;
virtual bool SetCurrentFolder(const TCHAR *path, TCHAR *buffer, size_t maxchars) =0;
virtual bool SendFile(const TCHAR *path, TCHAR *buffer, size_t maxchars) =0;
virtual bool CreateFolder(const TCHAR *name, TCHAR *buffer, size_t maxchars) =0;
virtual void CancelCurrentCopy() =0;
};
#endif //_INCLUDE_INSTALLER_COPY_METHOD_H_
+142
View File
@@ -0,0 +1,142 @@
#include "InstallerMain.h"
#include "Welcome.h"
#define WMU_INIT_INSTALLER WM_USER+1
HINSTANCE g_hInstance;
NEXT_DIALOG next_dialog = DisplayWelcome;
POINT g_GlobalPosition;
void UpdateGlobalPosition(HWND hWnd)
{
WINDOWINFO wi;
wi.cbSize = sizeof(WINDOWINFO);
if (GetWindowInfo(hWnd, &wi))
{
g_GlobalPosition.x = wi.rcWindow.left;
g_GlobalPosition.y = wi.rcWindow.top;
}
}
void SetToGlobalPosition(HWND hWnd)
{
WINDOWINFO wi;
wi.cbSize = sizeof(WINDOWINFO);
if (GetWindowInfo(hWnd, &wi))
{
MoveWindow(hWnd,
g_GlobalPosition.x,
g_GlobalPosition.y,
wi.rcWindow.right - wi.rcWindow.left,
wi.rcWindow.bottom - wi.rcWindow.top,
TRUE);
}
}
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WMU_INIT_INSTALLER:
{
UpdateGlobalPosition(hWnd);
while (next_dialog != NULL)
{
next_dialog = (NEXT_DIALOG)next_dialog(hWnd);
}
PostQuitMessage(0);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wcex;
BOOL bRet;
wcex.cbSize = sizeof(wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = MainWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_INSTALLER));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = _T("InstallerMenu");
wcex.lpszClassName = _T("Installer");
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
if (!RegisterClassEx(&wcex))
{
return 1;
}
INITCOMMONCONTROLSEX ccex;
ccex.dwSize = sizeof(ccex);
ccex.dwICC = ICC_BAR_CLASSES
|ICC_HOTKEY_CLASS
|ICC_LISTVIEW_CLASSES
|ICC_PROGRESS_CLASS
|ICC_WIN95_CLASSES
|ICC_TAB_CLASSES;
if (!InitCommonControlsEx(&ccex))
{
return 1;
}
g_hInstance = hInstance;
HWND hWnd = CreateWindow(
_T("Installer"),
_T("InstallerMain"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
(HWND)NULL,
(HMENU)NULL,
hInstance,
NULL);
if (hWnd == NULL)
{
return 1;
}
ShowWindow(hWnd, SW_HIDE);
UpdateWindow(hWnd);
PostMessage(hWnd, WMU_INIT_INSTALLER, 0, 0);
MSG msg;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
return 1;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef _INCLUDE_INSTALLER_H_
#define _INCLUDE_INSTALLER_H_
#include "platform_headers.h"
#include "Resource.h"
void UpdateGlobalPosition(HWND hWnd);
void SetToGlobalPosition(HWND hWnd);
typedef void *(*NEXT_DIALOG)(HWND);
extern HINSTANCE g_hInstance;
#endif //_INCLUDE_INSTALLER_H_
+312
View File
@@ -0,0 +1,312 @@
#include "InstallerUtil.h"
#include "InstallerMain.h"
#include <stdio.h>
#include <windows.h>
int tstrcasecmp(const TCHAR *str1, const TCHAR *str2)
{
#if defined _UNICODE
return _wcsicmp(str1, str2);
#else
return _stricmp(str1, str2);
#endif
}
size_t AnsiToUnicode(const char *str, wchar_t *buffer, size_t maxchars)
{
if (maxchars < 1)
{
return 0;
}
size_t total =
(size_t)MultiByteToWideChar(CP_UTF8,
0,
str,
-1,
buffer,
(int)maxchars);
return total;
}
bool IsWhiteSpaceA(const char *stream)
{
char c = *stream;
if (c & (1<<7))
{
return false;
}
else
{
return isspace(c) != 0;
}
}
int BreakStringA(const char *str, char *out, size_t maxchars)
{
const char *inptr = str;
while (*inptr != '\0' && IsWhiteSpaceA(inptr))
{
inptr++;
}
if (*inptr == '\0')
{
if (maxchars)
{
*out = '\0';
}
return -1;
}
const char *start, *end = NULL;
bool quoted = (*inptr == '"');
if (quoted)
{
inptr++;
start = inptr;
/* Read input until we reach a quote. */
while (*inptr != '\0' && *inptr != '"')
{
/* Update the end point, increment the stream. */
end = inptr++;
}
/* Read one more token if we reached an end quote */
if (*inptr == '"')
{
inptr++;
}
}
else
{
start = inptr;
/* Read input until we reach a space */
while (*inptr != '\0' && !IsWhiteSpaceA(inptr))
{
/* Update the end point, increment the stream. */
end = inptr++;
}
}
/* Copy the string we found, if necessary */
if (end == NULL)
{
if (maxchars)
{
*out = '\0';
}
}
else if (maxchars)
{
char *outptr = out;
maxchars--;
for (const char *ptr=start;
(ptr <= end) && ((unsigned)(outptr - out) < (maxchars));
ptr++, outptr++)
{
*outptr = *ptr;
}
*outptr = '\0';
}
/* Consume more of the string until we reach non-whitespace */
while (*inptr != '\0' && IsWhiteSpaceA(inptr))
{
inptr++;
}
return (int)(inptr - str);
}
size_t UTIL_Format(TCHAR *buffer, size_t count, const TCHAR *fmt, ...)
{
va_list ap;
size_t len;
va_start(ap, fmt);
len = UTIL_FormatArgs(buffer, count, fmt, ap);
va_end(ap);
if (len >= count)
{
len = count - 1;
buffer[len] = '\0';
}
return len;
}
size_t UTIL_FormatArgs(TCHAR *buffer, size_t count, const TCHAR *fmt, va_list ap)
{
size_t len = _vsntprintf(buffer, count, fmt, ap);
if (len >= count)
{
len = count - 1;
buffer[len] = '\0';
}
return len;
}
size_t UTIL_PathFormat(TCHAR *buffer, size_t count, const TCHAR *fmt, ...)
{
va_list ap;
size_t len;
va_start(ap, fmt);
len = UTIL_FormatArgs(buffer, count, fmt, ap);
va_end(ap);
for (size_t i = 0; i < len; i++)
{
if (buffer[i] == '/')
{
buffer[i] = '\\';
}
}
return len;
}
const TCHAR *GetFileFromPath(const TCHAR *path)
{
size_t len = _tcslen(path);
for (size_t i = len - 1;
i >= 0 && i < len;
i--)
{
if (path[i] == '\\' || path[i] == '/')
{
return &path[i+1];
}
}
return NULL;
}
void GenerateErrorMessage(DWORD err, TCHAR *buffer, size_t maxchars)
{
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
buffer,
(DWORD)maxchars,
NULL) == 0)
{
UTIL_Format(buffer, maxchars, _T("Unknown error"));
}
}
INT_PTR AskToExit(HWND hWnd)
{
TCHAR verify_exit[100];
if (LoadString(g_hInstance,
IDS_VERIFY_EXIT,
verify_exit,
sizeof(verify_exit) / sizeof(TCHAR)
) == 0)
{
return (INT_PTR)FALSE;
}
int val = MessageBox(
hWnd,
_T("Are you sure you want to exit?"),
_T("SourceMod Installer"),
MB_YESNO|MB_ICONQUESTION);
if (val == 0 || val == IDYES)
{
UpdateGlobalPosition(hWnd);
EndDialog(hWnd, NULL);
return (INT_PTR)TRUE;
}
return (INT_PTR)FALSE;
}
size_t UTIL_GetFileSize(const TCHAR *file_path)
{
HANDLE hFile;
if ((hFile = CreateFile(file_path,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL))
!= INVALID_HANDLE_VALUE)
{
LARGE_INTEGER size;
if (GetFileSizeEx(hFile, &size))
{
CloseHandle(hFile);
return (size_t)size.QuadPart;
}
CloseHandle(hFile);
}
return 0;
}
#if 0
size_t UTIL_GetFolderSize(const TCHAR *basepath)
{
HANDLE hFind;
WIN32_FIND_DATA fd;
TCHAR search_path[MAX_PATH];
size_t total = 0;
UTIL_PathFormat(search_path,
sizeof(search_path) / sizeof(TCHAR),
_T("%s\\*.*"),
basepath);
if ((hFind = FindFirstFile(search_path, &fd)) == INVALID_HANDLE_VALUE)
{
return 0;
}
do
{
if (tstrcasecmp(fd.cFileName, _T(".")) == 0
|| tstrcasecmp(fd.cFileName, _T("..")) == 0)
{
continue;
}
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
{
UTIL_PathFormat(search_path,
sizeof(search_path) / sizeof(TCHAR),
_T("%s\\%s"),
basepath,
fd.cFileName);
total += UTIL_GetFolderSize(search_path);
}
else
{
UTIL_PathFormat(search_path,
sizeof(search_path) / sizeof(TCHAR),
_T("%s\\%s"),
basepath,
fd.cFileName);
total += UTIL_GetFileSize(search_path);
}
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
return total;
}
#endif
+20
View File
@@ -0,0 +1,20 @@
#ifndef _INCLUDE_INSTALLER_UTIL_H_
#define _INCLUDE_INSTALLER_UTIL_H_
#include "platform_headers.h"
bool IsWhiteSpaceA(const char *stream);
size_t UTIL_FormatArgs(TCHAR *buffer, size_t count, const TCHAR *fmt, va_list ap);
size_t UTIL_Format(TCHAR *buffer, size_t count, const TCHAR *fmt, ...);
size_t UTIL_PathFormat(TCHAR *buffer, size_t count, const TCHAR *fmt, ...);
int tstrcasecmp(const TCHAR *str1, const TCHAR *str2);
int BreakStringA(const char *str, char *out, size_t maxchars);
size_t AnsiToUnicode(const char *str, wchar_t *buffer, size_t maxchars);
const TCHAR *GetFileFromPath(const TCHAR *path);
void GenerateErrorMessage(DWORD err, TCHAR *buffer, size_t maxchars);
size_t UTIL_GetFileSize(const TCHAR *file_path);
size_t UTIL_GetFolderSize(const TCHAR *basepath);
INT_PTR AskToExit(HWND hWnd);
#endif //_INCLUDE_INSTALLER_UTIL_H_
+167
View File
@@ -0,0 +1,167 @@
#include "InstallerUtil.h"
#include "LocalCopyMethod.h"
LocalCopyMethod g_LocalCopier;
DWORD CALLBACK CopyProgressRoutine(LARGE_INTEGER TotalFileSize,
LARGE_INTEGER TotalBytesTransferred,
LARGE_INTEGER StreamSize,
LARGE_INTEGER StreamBytesTransferred,
DWORD dwStreamNumber,
DWORD dwCallbackReason,
HANDLE hSourceFile,
HANDLE hDestinationFile,
LPVOID lpData)
{
ICopyProgress *progress = (ICopyProgress *)lpData;
progress->UpdateProgress((size_t)TotalBytesTransferred.QuadPart,
(size_t)TotalFileSize.QuadPart);
return PROGRESS_CONTINUE;
}
LocalCopyMethod::LocalCopyMethod()
{
m_pProgress = NULL;
}
void LocalCopyMethod::SetOutputPath(const TCHAR *path)
{
UTIL_PathFormat(m_OutputPath,
sizeof(m_OutputPath) / sizeof(TCHAR),
_T("%s"),
path);
UTIL_PathFormat(m_CurrentPath,
sizeof(m_CurrentPath) / sizeof(TCHAR),
_T("%s"),
path);
}
void LocalCopyMethod::TrackProgress(ICopyProgress *pProgress)
{
m_pProgress = pProgress;
}
bool LocalCopyMethod::CreateFolder(const TCHAR *name, TCHAR *buffer, size_t maxchars)
{
TCHAR path[MAX_PATH];
UTIL_PathFormat(path,
sizeof(path) / sizeof(TCHAR),
_T("%s\\%s"),
m_CurrentPath,
name);
if (CreateDirectory(path, NULL))
{
return true;
}
DWORD error = GetLastError();
if (error == ERROR_ALREADY_EXISTS)
{
return true;
}
GenerateErrorMessage(error, buffer, maxchars);
return false;
}
bool LocalCopyMethod::SetCurrentFolder(const TCHAR *path, TCHAR *buffer, size_t maxchars)
{
if (path == NULL)
{
UTIL_PathFormat(m_CurrentPath,
sizeof(m_CurrentPath) / sizeof(TCHAR),
_T("%s"),
m_OutputPath);
}
else
{
UTIL_PathFormat(m_CurrentPath,
sizeof(m_CurrentPath) / sizeof(TCHAR),
_T("%s\\%s"),
m_OutputPath,
path);
}
return true;
}
bool LocalCopyMethod::SendFile(const TCHAR *path, TCHAR *buffer, size_t maxchars)
{
const TCHAR *filename = GetFileFromPath(path);
if (filename == NULL)
{
UTIL_Format(buffer, maxchars, _T("Invalid filename"));
return false;
}
TCHAR new_path[MAX_PATH];
UTIL_PathFormat(new_path,
sizeof(new_path) / sizeof(TCHAR),
_T("%s\\%s"),
m_CurrentPath,
filename);
m_bCancelStatus = FALSE;
if (m_pProgress != NULL)
{
m_pProgress->StartingNewFile(filename);
}
if (CopyFileEx(path,
new_path,
m_pProgress ? CopyProgressRoutine : NULL,
m_pProgress,
&m_bCancelStatus,
0) == 0)
{
/* Delete the file in case it was a partial copy */
DeleteFile(new_path);
GenerateErrorMessage(GetLastError(), buffer, maxchars);
return false;
}
if (m_pProgress != NULL)
{
m_pProgress->FileDone(UTIL_GetFileSize(path));
}
return true;
}
void LocalCopyMethod::CancelCurrentCopy()
{
m_bCancelStatus = TRUE;
}
bool LocalCopyMethod::CheckForExistingInstall()
{
TCHAR path[MAX_PATH];
UTIL_PathFormat(path,
sizeof(path) / sizeof(TCHAR),
_T("%s\\addons\\sourcemod"),
m_CurrentPath);
if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
{
UTIL_PathFormat(path,
sizeof(path) / sizeof(TCHAR),
_T("%s\\cfg\\sourcemod"),
m_CurrentPath);
if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
{
return false;
}
}
return true;
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef _INCLUDE_INSTALL_LOCAL_COPY_METHOD_H_
#define _INCLUDE_INSTALL_LOCAL_COPY_METHOD_H_
#include "platform_headers.h"
#include "ICopyMethod.h"
class LocalCopyMethod : public ICopyMethod
{
public:
LocalCopyMethod();
public:
virtual void TrackProgress(ICopyProgress *pProgress);
virtual bool SetCurrentFolder(const TCHAR *path, TCHAR *buffer, size_t maxchars);
virtual bool SendFile(const TCHAR *path, TCHAR *buffer, size_t maxchars);
virtual bool CreateFolder(const TCHAR *name, TCHAR *buffer, size_t maxchars);
virtual void CancelCurrentCopy();
virtual bool CheckForExistingInstall();
public:
void SetOutputPath(const TCHAR *path);
private:
ICopyProgress *m_pProgress;
TCHAR m_OutputPath[MAX_PATH];
TCHAR m_CurrentPath[MAX_PATH];
BOOL m_bCancelStatus;
};
extern LocalCopyMethod g_LocalCopier;
#endif //_INCLUDE_INSTALL_LOCAL_COPY_METHOD_H_
+438
View File
@@ -0,0 +1,438 @@
#include "InstallerMain.h"
#include "InstallerUtil.h"
#include "PerformInstall.h"
#include "CCriticalSection.h"
#define WMU_INSTALLER_DONE WM_USER+2
#define PBAR_RANGE_HIGH 100
#define PBAR_RANGE_LOW 0
ICopyMethod *g_pCopyMethod = NULL;
HANDLE g_hCopyThread = NULL;
copy_thread_args_t g_thread_args = {NULL, NULL, NULL, false, false};
CCriticalSection g_update_window;
class TrackProgress : public ICopyProgress
{
public:
void Initialize(HWND hTextBar, HWND hCurBar, HWND hTotalBar, size_t total_size)
{
m_hTextBar = hTextBar;
m_hCurBar = hCurBar;
m_hTotalBar = hTotalBar;
m_TotalSize = total_size;
m_TotalDone = 0;
RedrawProgressBars(0.0, 0.0);
}
void Finished()
{
RedrawProgressBars(100.0, 100.0);
}
public:
void StartingNewFile(const TCHAR *filename)
{
TCHAR buffer[255];
if (g_update_window.TryEnter())
{
UTIL_Format(buffer, sizeof(buffer) / sizeof(TCHAR), _T("Copying: %s"), filename);
SendMessage(m_hTextBar, WM_SETTEXT, 0, (LPARAM)buffer);
UpdateWindow(m_hTextBar);
g_update_window.Leave();
}
}
void UpdateProgress(size_t bytes, size_t total_bytes)
{
float fCur = (float)bytes / (float)total_bytes;
float fTotal = ((float)m_TotalDone + (float)bytes) / (float)m_TotalSize;
RedrawProgressBars(fCur, fTotal);
}
void FileDone(size_t total_size)
{
m_TotalDone += total_size;
RedrawProgressBars(0.0, (float)m_TotalDone / (float)m_TotalSize);
}
private:
void RedrawProgressBar(HWND hBar, float fPerc)
{
/* Get a percentage point in the range */
float fPointInRange = (float)(PBAR_RANGE_HIGH - PBAR_RANGE_LOW) * fPerc;
int iPointInRange = (int)fPointInRange;
/* Scale it */
iPointInRange += PBAR_RANGE_LOW;
if (g_update_window.TryEnter())
{
SendMessage(hBar,
PBM_SETPOS,
iPointInRange,
0);
g_update_window.Leave();
}
}
void RedrawProgressBars(float fCurrent, float fTotal)
{
RedrawProgressBar(m_hCurBar, fCurrent);
RedrawProgressBar(m_hTotalBar, fTotal);
}
private:
size_t m_TotalSize;
size_t m_TotalDone;
HWND m_hTextBar;
HWND m_hCurBar;
HWND m_hTotalBar;
} s_ProgressTracker;
void CancelPerformInstall()
{
delete g_thread_args.pFileList;
g_thread_args.pFileList = NULL;
}
void SetInstallMethod(ICopyMethod *pCopyMethod)
{
g_pCopyMethod = pCopyMethod;
}
bool CopyStructureRecursively(ICopyMethod *pCopyMethod,
CFileList *pFileList,
const TCHAR *basepath,
const TCHAR *local_path,
TCHAR *errbuf,
size_t maxchars)
{
TCHAR file_path[MAX_PATH];
const TCHAR *file;
CFileList *pSubList;
if (!pCopyMethod->SetCurrentFolder(local_path, errbuf, maxchars))
{
return false;
}
/* Copy files */
while ((file = pFileList->PeekCurrentFile()) != NULL)
{
if (local_path == NULL)
{
UTIL_PathFormat(file_path,
sizeof(file_path) / sizeof(TCHAR),
_T("%s\\%s"),
basepath,
file);
}
else
{
UTIL_PathFormat(file_path,
sizeof(file_path) / sizeof(TCHAR),
_T("%s\\%s\\%s"),
basepath,
local_path,
file);
}
if (!pCopyMethod->SendFile(file_path, errbuf, maxchars))
{
return false;
}
pFileList->PopCurrentFile();
}
/* Now copy folders */
while ((pSubList = pFileList->PeekCurrentFolder()) != NULL)
{
if (g_thread_args.m_bIsUpgrade)
{
/* :TODO: put this somewhere else because it technically
* means the progress bars get calculated wrong
*/
if (tstrcasecmp(pSubList->GetFolderName(), _T("cfg")) == 0
|| tstrcasecmp(pSubList->GetFolderName(), _T("configs")) == 0)
{
pFileList->PopCurrentFolder();
continue;
}
}
/* Try creating the folder */
if (!pCopyMethod->CreateFolder(pSubList->GetFolderName(), errbuf, maxchars))
{
return false;
}
TCHAR new_local_path[MAX_PATH];
if (local_path == NULL)
{
UTIL_PathFormat(new_local_path,
sizeof(new_local_path) / sizeof(TCHAR),
_T("%s"),
pSubList->GetFolderName());
}
else
{
UTIL_PathFormat(new_local_path,
sizeof(new_local_path) / sizeof(TCHAR),
_T("%s\\%s"),
local_path,
pSubList->GetFolderName());
}
if (!CopyStructureRecursively(pCopyMethod,
pSubList,
basepath,
new_local_path,
errbuf,
maxchars))
{
return false;
}
pFileList->PopCurrentFolder();
/* Set the current folder again for the next operation */
if (!pCopyMethod->SetCurrentFolder(local_path, errbuf, maxchars))
{
return false;
}
}
return true;
}
DWORD WINAPI T_CopyFiles(LPVOID arg)
{
bool result =
CopyStructureRecursively(g_thread_args.pCopyMethod,
g_thread_args.pFileList,
g_thread_args.basepath,
NULL,
g_thread_args.error,
sizeof(g_thread_args.error) / sizeof(TCHAR));
PostMessage(g_thread_args.hWnd, WMU_INSTALLER_DONE, result ? TRUE : FALSE, 0);
return 0;
}
bool StartFileCopy(HWND hWnd)
{
g_thread_args.m_bWasCancelled = false;
g_thread_args.hWnd = hWnd;
if ((g_hCopyThread = CreateThread(NULL,
0,
T_CopyFiles,
NULL,
0,
NULL))
== NULL)
{
MessageBox(
hWnd,
_T("Could not initialize copy thread."),
_T("SourceMod Installer"),
MB_OK|MB_ICONERROR);
return false;
}
return true;
}
void StopFileCopy()
{
g_thread_args.m_bWasCancelled = true;
g_pCopyMethod->CancelCurrentCopy();
if (g_hCopyThread != NULL)
{
g_update_window.Enter();
WaitForSingleObject(g_hCopyThread, INFINITE);
g_update_window.Leave();
CloseHandle(g_hCopyThread);
g_hCopyThread = NULL;
}
}
bool RequestCancelInstall(HWND hWnd)
{
StopFileCopy();
int val = MessageBox(
hWnd,
_T("Are you sure you want to cancel the install?"),
_T("SourceMod Installer"),
MB_YESNO|MB_ICONQUESTION);
if (val == IDYES)
{
return true;
}
if (g_thread_args.pFileList == NULL)
{
return false;
}
/* Start the thread, note our return value is opposite */
return !StartFileCopy(hWnd);
}
bool StartInstallProcess(HWND hWnd)
{
if (g_pCopyMethod->CheckForExistingInstall())
{
int val = MessageBox(
hWnd,
_T("It looks like a previous SourceMod installation exists. Select \"Yes\" to skip copying configuration files. Select \"No\" to perform a full re-install."),
_T("SourceMod Installer"),
MB_YESNO|MB_ICONQUESTION);
if (val == 0 || val == IDYES)
{
g_thread_args.m_bIsUpgrade = true;
}
else
{
g_thread_args.m_bIsUpgrade = false;
}
}
#if 0
TCHAR cur_path[MAX_PATH];
if (_tgetcwd(cur_path, sizeof(cur_path)) == NULL)
{
MessageBox(
hWnd,
_T("Could not locate current directory!"),
_T("SourceMod Installer"),
MB_OK|MB_ICONERROR);
return false;
}
#endif
#if 0
UTIL_PathFormat(source_path,
sizeof(source_path) / sizeof(TCHAR),
_T("%s\\files"),
cur_path);
#else
UTIL_PathFormat(g_thread_args.basepath,
sizeof(g_thread_args.basepath) / sizeof(TCHAR),
_T("C:\\real\\done\\base"));
#endif
if (GetFileAttributes(g_thread_args.basepath) == INVALID_FILE_ATTRIBUTES)
{
MessageBox(
hWnd,
_T("Could not locate the source installation files!"),
_T("SourceMod Installer"),
MB_OK|MB_ICONERROR);
return false;
}
delete g_thread_args.pFileList;
g_thread_args.pFileList = CFileList::BuildFileList(_T(""), g_thread_args.basepath);
s_ProgressTracker.Initialize(
GetDlgItem(hWnd, IDC_PROGRESS_CURCOPY),
GetDlgItem(hWnd, IDC_PROGRESS_CURRENT),
GetDlgItem(hWnd, IDC_PROGRESS_TOTAL),
(size_t)g_thread_args.pFileList->GetRecursiveSize());
g_pCopyMethod->TrackProgress(&s_ProgressTracker);
g_thread_args.pCopyMethod = g_pCopyMethod;
return StartFileCopy(hWnd);
}
INT_PTR CALLBACK PerformInstallHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
SetToGlobalPosition(hDlg);
return (INT_PTR)TRUE;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == ID_INSTALL_CANCEL
|| LOWORD(wParam) == ID_CLOSE)
{
if (RequestCancelInstall(hDlg))
{
CancelPerformInstall();
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, NULL);
}
return (INT_PTR)TRUE;
}
else if (LOWORD(wParam) == ID_INSTALL_START)
{
HWND hButton = GetDlgItem(hDlg, ID_INSTALL_START);
EnableWindow(hButton, FALSE);
StartInstallProcess(hDlg);
}
break;
}
case WMU_INSTALLER_DONE:
{
if (wParam == TRUE)
{
s_ProgressTracker.Finished();
MessageBox(hDlg,
_T("SourceMod was successfully installed! Please visit http://www.sourcemod.net/ for documentation."),
_T("SourceMod Installer"),
MB_OK);
CancelPerformInstall();
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, NULL);
return (INT_PTR)TRUE;
}
else if (!g_thread_args.m_bWasCancelled)
{
TCHAR buffer[500];
UTIL_Format(buffer,
sizeof(buffer) / sizeof(TCHAR),
_T("Encountered error: %s"),
g_thread_args.error);
int res = MessageBox(hDlg,
buffer,
_T("SourceMod Installer"),
MB_ICONERROR|MB_RETRYCANCEL);
if (res == IDRETRY)
{
StartFileCopy(hDlg);
}
else
{
CancelPerformInstall();
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, NULL);
return (INT_PTR)TRUE;
}
}
break;
}
}
return (INT_PTR)FALSE;
}
void *DisplayPerformInstall(HWND hWnd)
{
INT_PTR val;
if ((val = DialogBox(
g_hInstance,
MAKEINTRESOURCE(IDD_PERFORM_INSTALL),
hWnd,
PerformInstallHandler)) == -1)
{
return NULL;
}
return (void *)val;
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef _INCLUDE_PERFORM_INSTALL_H_
#define _INCLUDE_PERFORM_INSTALL_H_
#include "InstallerMain.h"
#include "ICopyMethod.h"
#include "CFileList.h"
struct copy_thread_args_t
{
ICopyMethod *pCopyMethod;
CFileList *pFileList;
HWND hWnd;
bool m_bIsUpgrade;
bool m_bWasCancelled;
TCHAR basepath[MAX_PATH];
TCHAR error[255];
};
void *DisplayPerformInstall(HWND hWnd);
void SetInstallMethod(ICopyMethod *pCopyMethod);
#endif //_INCLUDE_PERFORM_INSTALL_H_
+65
View File
@@ -0,0 +1,65 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by installer.rc
//
#define ID_CLOSE 2
#define IDD_INSTALLER_DIALOG 102
#define IDS_APP_TITLE 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDI_INSTALLER 107
#define IDI_SMALL 108
#define IDC_INSTALLER 109
#define IDR_MAINFRAME 128
#define IDD_WELCOME 130
#define IDD_CHOOSE_METHOD 132
#define IDS_NO_GAMEINFO 132
#define IDS_READONLY_GAMEINFO 133
#define IDS_GAME_FAIL_HL1 134
#define IDS_GAME_FAIL_READ 135
#define IDS_GAME_FAIL_NONE 136
#define IDS_VERIFY_EXIT 137
#define ID_WELCOME_NEXT 1001
#define IDC_WELCOME_PANEL 1002
#define IDC_METHOD_TEXT 1003
#define ID_WELCOME_EXIT 1003
#define ID_METHOD_NEXT 1004
#define ID_METHOD_EXIT 1005
#define ID_METHOD_BACK 1006
#define IDC_METHOD_DED_SERVER 1007
#define IDC_METHOD_LISTEN_SERVER 1008
#define IDC_SELGAME_LIST 1008
#define IDC_METHOD_ALONE_SERVER 1009
#define IDC_PROGRESS_CURRENT 1009
#define IDC_METHOD_CUSTOM_FOLDER 1010
#define IDC_PROGRESS_TOTAL 1010
#define IDC_METHOD_UPLOAD_FTP 1011
#define ID_SELGAME_NEXT 1012
#define ID_SELGAME_EXIT 1013
#define ID_SELGAME_BACK 1014
#define IDC_SELGAME_TEXT 1015
#define IDC_SELGAME_PANEL 1016
#define IDD_SELECT_GAME 1017
#define IDD_PERFORM_INSTALL 1018
#define ID_INSTALL_CANCEL 1019
#define IDC_INSTALL_PANEL 1020
#define IDC_INSTALL_TEXT 1021
#define IDC_COMBO3 1021
#define IDC_SELGROUP_ACCOUNT 1021
#define ID_INSTALL_START 1022
#define IDC_PROGRESS_CURCOPY 1023
#define IDC_STATIC -1
#define IDC_WELCOME_TEXT -1
#define IDC_METHOD_PANEL -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 133
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1022
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif
+169
View File
@@ -0,0 +1,169 @@
#include "InstallerMain.h"
#include "InstallerUtil.h"
#include "SelectGame.h"
#include "GamesList.h"
#include "ChooseMethod.h"
#include "PerformInstall.h"
#include "LocalCopyMethod.h"
int selected_game_index = -1;
void UpdateGameListBox(HWND hDlg, game_list_t *gl)
{
HWND lbox = GetDlgItem(hDlg, IDC_SELGAME_LIST);
SendMessage(lbox, LB_RESETCONTENT, 0, 0);
for (unsigned int i = 0; i < gl->game_count; i++)
{
LRESULT res = SendMessage(lbox,
LB_ADDSTRING,
0,
(LPARAM)g_games.game_list[gl->games[i]].name);
if (res == LB_ERR || res == LB_ERRSPACE)
{
continue;
}
SendMessage(lbox, LB_SETITEMDATA, i, gl->games[i]);
}
UpdateWindow(lbox);
}
#include "windowsx.h"
INT_PTR CALLBACK ChooseGameHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
HWND cbox = GetDlgItem(hDlg, IDC_SELGROUP_ACCOUNT);
SendMessage(cbox, CB_RESETCONTENT, 0, 0);
for (unsigned int i = 0; i < g_game_group->list_count; i++)
{
LRESULT res = SendMessage(cbox,
CB_ADDSTRING,
0,
(LPARAM)g_game_group->lists[i]->root_name);
if (res == CB_ERR || res == CB_ERRSPACE)
{
continue;
}
SendMessage(cbox, CB_SETITEMDATA, i, (LPARAM)g_game_group->lists[i]);
}
SendMessage(cbox, CB_SETCURSEL, 0, 0);
UpdateWindow(cbox);
UpdateGameListBox(hDlg, g_game_group->lists[0]);
SetToGlobalPosition(hDlg);
return (INT_PTR)TRUE;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == ID_SELGAME_EXIT
|| LOWORD(wParam) == ID_CLOSE)
{
return AskToExit(hDlg);
}
else if (LOWORD(wParam) == ID_SELGAME_BACK)
{
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, (INT_PTR)DisplayChooseMethod);
return (INT_PTR)TRUE;
}
else if (LOWORD(wParam) == IDC_SELGROUP_ACCOUNT)
{
if (HIWORD(wParam) == CBN_SELCHANGE)
{
HWND cbox = (HWND)lParam;
LRESULT cursel = SendMessage(cbox, CB_GETCURSEL, 0, 0);
if (cursel == LB_ERR)
{
break;
}
LRESULT data = SendMessage(cbox, CB_GETITEMDATA, cursel, 0);
if (data == CB_ERR)
{
break;
}
game_list_t *gl = (game_list_t *)data;
UpdateGameListBox(hDlg, gl);
}
break;
}
else if (LOWORD(wParam) == IDC_SELGAME_LIST)
{
if (HIWORD(wParam) == LBN_SELCHANGE)
{
HWND lbox = (HWND)lParam;
LRESULT cursel = SendMessage(lbox, LB_GETCURSEL, 0, 0);
selected_game_index = -1;
if (cursel == LB_ERR)
{
break;
}
LRESULT item = SendMessage(lbox, LB_GETITEMDATA, cursel, 0);
if (item == LB_ERR)
{
break;
}
selected_game_index = (int)item;
HWND button = GetDlgItem(hDlg, ID_SELGAME_NEXT);
EnableWindow(button, TRUE);
}
}
else if (LOWORD(wParam) == ID_SELGAME_NEXT)
{
if (selected_game_index == -1)
{
break;
}
g_LocalCopier.SetOutputPath(g_games.game_list[selected_game_index].game_path);
SetInstallMethod(&g_LocalCopier);
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, (INT_PTR)DisplayPerformInstall);
return (INT_PTR)TRUE;
}
break;
}
case WM_DESTROY:
{
ReleaseGameDB();
break;
}
}
return (INT_PTR)FALSE;
}
void *DisplaySelectGame(HWND hWnd)
{
INT_PTR val;
if ((val = DialogBox(
g_hInstance,
MAKEINTRESOURCE(IDD_SELECT_GAME),
hWnd,
ChooseGameHandler)) == -1)
{
return NULL;
}
return (void *)val;
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef _INCLUDE_INSTALLER_SELECT_GAME_H_
#define _INCLUDE_INSTALLER_SELECT_GAME_H_
#include "InstallerMain.h"
void *DisplaySelectGame(HWND hWnd);
#endif //_INCLUDE_INSTALLER_SELECT_GAME_H_
+60
View File
@@ -0,0 +1,60 @@
#include "InstallerMain.h"
#include "Welcome.h"
#include "ChooseMethod.h"
bool g_bIsFirstRun = true;
INT_PTR CALLBACK WelcomeHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
if (!g_bIsFirstRun)
{
SetToGlobalPosition(hDlg);
}
else
{
g_bIsFirstRun = false;
}
return (INT_PTR)TRUE;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == ID_WELCOME_EXIT
|| LOWORD(wParam) == ID_CLOSE)
{
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, NULL);
return (INT_PTR)TRUE;
}
else if (LOWORD(wParam) == ID_WELCOME_NEXT)
{
UpdateGlobalPosition(hDlg);
EndDialog(hDlg, (INT_PTR)DisplayChooseMethod);
return (INT_PTR)TRUE;
}
break;
}
}
return (INT_PTR)FALSE;
}
void *DisplayWelcome(HWND hWnd)
{
INT_PTR val;
if ((val = DialogBox(
g_hInstance,
MAKEINTRESOURCE(IDD_WELCOME),
hWnd,
WelcomeHandler)) == -1)
{
return NULL;
}
return (void *)val;
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef _INCLUDE_INSTALLER_WELCOME_H_
#define _INCLUDE_INSTALLER_WELCOME_H_
void *DisplayWelcome(HWND hWnd);
#endif //_INCLUDE_INSTALLER_WELCOME_H_
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

+222
View File
@@ -0,0 +1,222 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_INSTALLER ICON "installer.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDC_INSTALLER MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDC_INSTALLER ACCELERATORS
BEGIN
"?", IDM_ABOUT, ASCII, ALT
"/", IDM_ABOUT, ASCII, ALT
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_WELCOME DIALOGEX 0, 0, 244, 74
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "SourceMod Installer"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "&Next",ID_WELCOME_NEXT,191,58,50,14
GROUPBOX "",IDC_WELCOME_PANEL,2,3,239,51
LTEXT "Welcome to the SourceMod Installer. This tool can be used to install SourcecMod to a local server/game installation, or upload SourceMod to a server via FTP.",IDC_WELCOME_TEXT,9,11,225,42
DEFPUSHBUTTON "E&xit",ID_WELCOME_EXIT,2,58,50,14
END
IDD_CHOOSE_METHOD DIALOGEX 0, 0, 244, 130
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "SourceMod Installer"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "&Next",ID_METHOD_NEXT,191,113,50,14,WS_DISABLED
PUSHBUTTON "E&xit",ID_METHOD_EXIT,2,113,50,14
GROUPBOX "",IDC_METHOD_PANEL,2,3,239,108
DEFPUSHBUTTON "&Back",ID_METHOD_BACK,136,113,50,14
GROUPBOX "",IDC_METHOD_PANEL,17,30,181,69
LTEXT "Please select an installation method:",IDC_METHOD_TEXT,9,15,122,12
CONTROL "Steam Dedicated Server",IDC_METHOD_DED_SERVER,"Button",BS_AUTORADIOBUTTON,21,35,98,15
CONTROL "Steam Listen Server",IDC_METHOD_LISTEN_SERVER,"Button",BS_AUTORADIOBUTTON,21,46,93,16
CONTROL "Standalone Server",IDC_METHOD_ALONE_SERVER,"Button",BS_AUTORADIOBUTTON,21,58,93,16
CONTROL "Select Destination Folder",IDC_METHOD_CUSTOM_FOLDER,
"Button",BS_AUTORADIOBUTTON,21,70,95,16
CONTROL "Upload via FTP",IDC_METHOD_UPLOAD_FTP,"Button",BS_AUTORADIOBUTTON,21,82,94,16
END
IDD_SELECT_GAME DIALOGEX 0, 0, 244, 148
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "SourceMod Installer"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "&Next",ID_SELGAME_NEXT,191,131,50,14,WS_DISABLED
PUSHBUTTON "E&xit",ID_SELGAME_EXIT,2,131,50,14
GROUPBOX "",IDC_SELGAME_PANEL,2,3,239,126
DEFPUSHBUTTON "&Back",ID_SELGAME_BACK,136,131,50,14
LTEXT "Please select a game from the list below. If there are multiple accounts, you may select one from the combo-box.",IDC_SELGAME_TEXT,7,14,221,16
LISTBOX IDC_SELGAME_LIST,17,46,199,76,LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_SELGROUP_ACCOUNT,17,32,133,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
END
IDD_PERFORM_INSTALL DIALOGEX 0, 0, 243, 116
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "SourceMod Installer"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "&Cancel",ID_INSTALL_CANCEL,2,99,50,14
GROUPBOX "",IDC_INSTALL_PANEL,2,3,239,93
LTEXT "Click ""Install"" to begin copying the SourceMod files.",IDC_INSTALL_TEXT,9,15,175,13
CONTROL "",IDC_PROGRESS_CURRENT,"msctls_progress32",WS_BORDER | 0x1,5,50,232,17
CONTROL "",IDC_PROGRESS_TOTAL,"msctls_progress32",WS_BORDER | 0x1,5,73,232,17
PUSHBUTTON "&Install",ID_INSTALL_START,191,99,50,14
LTEXT "",IDC_PROGRESS_CURCOPY,9,34,175,11
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_WELCOME, DIALOG
BEGIN
LEFTMARGIN, 2
RIGHTMARGIN, 241
TOPMARGIN, 3
BOTTOMMARGIN, 72
END
IDD_CHOOSE_METHOD, DIALOG
BEGIN
LEFTMARGIN, 2
RIGHTMARGIN, 241
TOPMARGIN, 3
BOTTOMMARGIN, 127
END
IDD_PERFORM_INSTALL, DIALOG
BEGIN
BOTTOMMARGIN, 113
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_NO_GAMEINFO "The folder you selected does not appear to be a valid Half-Life 2 game/mod folder."
IDS_READONLY_GAMEINFO "The folder you selected may contain a valid Half-Life 2 game/mod, but its gameinfo.txt is read-only. You must make it writable to continue."
IDS_GAME_FAIL_HL1 "A Source dedicated server installation could not be found. This may occur if you used the standalone server to install HLDS. Try navigating to the folder manually."
IDS_GAME_FAIL_READ "Could not locate a valid Source installation. Please make sure Steam is installed and its games have been run at least once."
IDS_GAME_FAIL_NONE "No Source games or mods were found. Please make sure that Steam is installed and its games have been run at least once."
IDS_VERIFY_EXIT "Are you sure you want to exit?"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer", "installer.vcproj", "{B2479B33-A265-423B-A996-F994546644F9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B2479B33-A265-423B-A996-F994546644F9}.Debug|Win32.ActiveCfg = Debug|Win32
{B2479B33-A265-423B-A996-F994546644F9}.Debug|Win32.Build.0 = Debug|Win32
{B2479B33-A265-423B-A996-F994546644F9}.Release|Win32.ActiveCfg = Release|Win32
{B2479B33-A265-423B-A996-F994546644F9}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+298
View File
@@ -0,0 +1,298 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="installer"
ProjectGUID="{B2479B33-A265-423B-A996-F994546644F9}"
RootNamespace="installer"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="comctl32.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\CFileList.cpp"
>
</File>
<File
RelativePath=".\GamesList.cpp"
>
</File>
<File
RelativePath=".\InstallerUtil.cpp"
>
</File>
<File
RelativePath=".\LocalCopyMethod.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CCriticalSection.h"
>
</File>
<File
RelativePath=".\CFileList.h"
>
</File>
<File
RelativePath=".\GamesList.h"
>
</File>
<File
RelativePath=".\ICopyMethod.h"
>
</File>
<File
RelativePath=".\InstallerUtil.h"
>
</File>
<File
RelativePath=".\LocalCopyMethod.h"
>
</File>
<File
RelativePath=".\platform_headers.h"
>
</File>
<File
RelativePath=".\Resource.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\installer.ico"
>
</File>
<File
RelativePath=".\installer.rc"
>
</File>
</Filter>
<Filter
Name="Window Headers"
>
<File
RelativePath=".\ChooseMethod.h"
>
</File>
<File
RelativePath=".\InstallerMain.h"
>
</File>
<File
RelativePath=".\PerformInstall.h"
>
</File>
<File
RelativePath=".\SelectGame.h"
>
</File>
<File
RelativePath=".\Welcome.h"
>
</File>
</Filter>
<Filter
Name="Window Source"
>
<File
RelativePath=".\ChooseMethod.cpp"
>
</File>
<File
RelativePath=".\InstallerMain.cpp"
>
</File>
<File
RelativePath=".\PerformInstall.cpp"
>
</File>
<File
RelativePath=".\SelectGame.cpp"
>
</File>
<File
RelativePath=".\Welcome.cpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+33
View File
@@ -0,0 +1,33 @@
#ifndef _INCLUDE_INSTALLER_PLATFORM_HEADERS_H_
#define _INCLUDE_INSTALLER_PLATFORM_HEADERS_H_
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows XP or later.
#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
#endif
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <commctrl.h>
#include <shlobj.h>
#endif //_INCLUDE_INSTALLER_PLATFORM_HEADERS_H_
+85
View File
@@ -0,0 +1,85 @@
using System;
using System.Collections;
using System.Text;
using System.Windows.Forms;
namespace profviewer
{
class LIStringComparator : IComparer
{
private int m_col;
public LIStringComparator(int col)
{
m_col = col;
}
public int Compare(object x, object y)
{
ListViewItem a = (ListViewItem)x;
ListViewItem b = (ListViewItem)y;
return String.Compare(a.SubItems[m_col].Text, b.SubItems[m_col].Text);
}
}
class LIIntComparator : IComparer
{
private int m_col;
public LIIntComparator(int col)
{
m_col = col;
}
public int Compare(object x, object y)
{
ListViewItem a = (ListViewItem)x;
ListViewItem b = (ListViewItem)y;
int num1 = Int32.Parse(a.SubItems[m_col].Text);
int num2 = Int32.Parse(b.SubItems[m_col].Text);
if (num1 > num2)
{
return -1;
}
else if (num1 < num2)
{
return 1;
}
return 0;
}
}
class LIDoubleComparator : IComparer
{
private int m_col;
public LIDoubleComparator(int col)
{
m_col = col;
}
public int Compare(object x, object y)
{
ListViewItem a = (ListViewItem)x;
ListViewItem b = (ListViewItem)y;
double num1 = Double.Parse(a.SubItems[m_col].Text);
double num2 = Double.Parse(b.SubItems[m_col].Text);
if (num1 > num2)
{
return -1;
}
else if (num1 < num2)
{
return 1;
}
return 0;
}
}
}
+243
View File
@@ -0,0 +1,243 @@
namespace profviewer
{
partial class Main
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.report_list = new System.Windows.Forms.ListView();
this.pr_type = new System.Windows.Forms.ColumnHeader();
this.pr_name = new System.Windows.Forms.ColumnHeader();
this.pr_calls = new System.Windows.Forms.ColumnHeader();
this.pr_avg_time = new System.Windows.Forms.ColumnHeader();
this.pr_min_time = new System.Windows.Forms.ColumnHeader();
this.pr_max_time = new System.Windows.Forms.ColumnHeader();
this.pr_total_time = new System.Windows.Forms.ColumnHeader();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menu_file_open = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.menu_file_exit = new System.Windows.Forms.ToolStripMenuItem();
this.label1 = new System.Windows.Forms.Label();
this.report_info_starttime = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.report_info_duration = new System.Windows.Forms.Label();
this.dialog_open = new System.Windows.Forms.OpenFileDialog();
this.panel1 = new System.Windows.Forms.Panel();
this.menuStrip1.SuspendLayout();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// report_list
//
this.report_list.AllowColumnReorder = true;
this.report_list.AutoArrange = false;
this.report_list.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.pr_type,
this.pr_name,
this.pr_calls,
this.pr_avg_time,
this.pr_min_time,
this.pr_max_time,
this.pr_total_time});
this.report_list.Dock = System.Windows.Forms.DockStyle.Fill;
this.report_list.Location = new System.Drawing.Point(0, 24);
this.report_list.MultiSelect = false;
this.report_list.Name = "report_list";
this.report_list.Size = new System.Drawing.Size(759, 300);
this.report_list.TabIndex = 0;
this.report_list.UseCompatibleStateImageBehavior = false;
this.report_list.View = System.Windows.Forms.View.Details;
this.report_list.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.report_list_ColumnClick);
//
// pr_type
//
this.pr_type.Text = "Type";
this.pr_type.Width = 71;
//
// pr_name
//
this.pr_name.Text = "Name";
this.pr_name.Width = 270;
//
// pr_calls
//
this.pr_calls.Text = "Calls";
this.pr_calls.Width = 61;
//
// pr_avg_time
//
this.pr_avg_time.Text = "Avg Time";
this.pr_avg_time.Width = 74;
//
// pr_min_time
//
this.pr_min_time.Text = "Min Time";
this.pr_min_time.Width = 78;
//
// pr_max_time
//
this.pr_max_time.Text = "Max Time";
this.pr_max_time.Width = 77;
//
// pr_total_time
//
this.pr_total_time.Text = "Total Time";
this.pr_total_time.Width = 84;
//
// menuStrip1
//
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(759, 24);
this.menuStrip1.TabIndex = 1;
this.menuStrip1.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.menu_file_open,
this.toolStripMenuItem1,
this.menu_file_exit});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// menu_file_open
//
this.menu_file_open.Name = "menu_file_open";
this.menu_file_open.Size = new System.Drawing.Size(100, 22);
this.menu_file_open.Text = "&Open";
this.menu_file_open.Click += new System.EventHandler(this.menu_file_open_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(97, 6);
//
// menu_file_exit
//
this.menu_file_exit.Name = "menu_file_exit";
this.menu_file_exit.Size = new System.Drawing.Size(100, 22);
this.menu_file_exit.Text = "E&xit";
this.menu_file_exit.Click += new System.EventHandler(this.menu_file_exit_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(3, 13);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(76, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Profile Started:";
//
// report_info_starttime
//
this.report_info_starttime.AutoSize = true;
this.report_info_starttime.Location = new System.Drawing.Point(79, 13);
this.report_info_starttime.Name = "report_info_starttime";
this.report_info_starttime.Size = new System.Drawing.Size(0, 13);
this.report_info_starttime.TabIndex = 3;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(264, 13);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(82, 13);
this.label2.TabIndex = 4;
this.label2.Text = "Profile Duration:";
//
// report_info_duration
//
this.report_info_duration.AutoSize = true;
this.report_info_duration.Location = new System.Drawing.Point(346, 13);
this.report_info_duration.Name = "report_info_duration";
this.report_info_duration.Size = new System.Drawing.Size(0, 13);
this.report_info_duration.TabIndex = 5;
//
// dialog_open
//
this.dialog_open.Filter = "Profiler files|*.xml|All files|*.*";
//
// panel1
//
this.panel1.Controls.Add(this.label1);
this.panel1.Controls.Add(this.report_info_duration);
this.panel1.Controls.Add(this.report_info_starttime);
this.panel1.Controls.Add(this.label2);
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel1.Location = new System.Drawing.Point(0, 324);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(759, 33);
this.panel1.TabIndex = 6;
//
// Main
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(759, 357);
this.Controls.Add(this.report_list);
this.Controls.Add(this.menuStrip1);
this.Controls.Add(this.panel1);
this.MainMenuStrip = this.menuStrip1;
this.Name = "Main";
this.Text = "SourceMod Profiler Report Viewer";
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ListView report_list;
private System.Windows.Forms.ColumnHeader pr_type;
private System.Windows.Forms.ColumnHeader pr_name;
private System.Windows.Forms.ColumnHeader pr_calls;
private System.Windows.Forms.ColumnHeader pr_avg_time;
private System.Windows.Forms.ColumnHeader pr_min_time;
private System.Windows.Forms.ColumnHeader pr_max_time;
private System.Windows.Forms.ColumnHeader pr_total_time;
private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem menu_file_open;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem menu_file_exit;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label report_info_starttime;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label report_info_duration;
private System.Windows.Forms.OpenFileDialog dialog_open;
private System.Windows.Forms.Panel panel1;
}
}
+98
View File
@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace profviewer
{
public partial class Main : Form
{
private ProfileReport m_Report;
public Main()
{
InitializeComponent();
}
private void menu_file_open_Click(object sender, EventArgs e)
{
DialogResult res;
res = dialog_open.ShowDialog(this);
if (res != DialogResult.OK)
{
return;
}
m_Report = null;
try
{
m_Report = new ProfileReport(dialog_open.FileName);
}
catch (System.Exception ex)
{
MessageBox.Show("Error opening or parsing file: " + ex.Message);
}
UpdateListView();
}
private void UpdateListView()
{
ProfileItem atom;
ListViewItem item;
if (m_Report == null)
{
report_list.Items.Clear();
report_info_duration.Text = "";
report_info_starttime.Text = "";
return;
}
report_info_duration.Text = m_Report.Duration.ToString() + " seconds";
report_info_starttime.Text = m_Report.StartTime.ToString();
for (int i = 0; i < m_Report.Count; i++)
{
atom = m_Report.GetItem(i);
item = new ListViewItem(ProfileReport.TypeStrings[(int)atom.type]);
item.SubItems.Add(atom.name);
item.SubItems.Add(atom.num_calls.ToString());
item.SubItems.Add(atom.AverageTime.ToString("F6"));
item.SubItems.Add(atom.min_time.ToString("F6"));
item.SubItems.Add(atom.max_time.ToString("F6"));
item.SubItems.Add(atom.total_time.ToString("F6"));
report_list.Items.Add(item);
}
}
private void menu_file_exit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void report_list_ColumnClick(object sender, ColumnClickEventArgs e)
{
if (e.Column == 1)
{
report_list.ListViewItemSorter = new LIStringComparator(1);
}
else if (e.Column == 2)
{
report_list.ListViewItemSorter = new LIIntComparator(2);
}
else if (e.Column > 2)
{
report_list.ListViewItemSorter = new LIDoubleComparator(e.Column);
}
}
}
}
+126
View File
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="dialog_open.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>126, 17</value>
</metadata>
</root>
+159
View File
@@ -0,0 +1,159 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace profviewer
{
enum ProfileType : int
{
ProfType_Unknown = 0,
ProfType_Native,
ProfType_Callback,
ProfType_Function
}
class ProfileItem
{
public string name;
public double total_time;
public uint num_calls;
public double min_time;
public double max_time;
public ProfileType type;
public double AverageTime
{
get
{
return total_time / num_calls;
}
}
}
class ProfileReport
{
public static string[] TypeStrings;
private DateTime m_start_time;
private double m_duration;
private List<ProfileItem> m_Items;
public int Count
{
get
{
return m_Items.Count;
}
}
static ProfileReport()
{
TypeStrings = new string[4];
TypeStrings[0] = "unknown";
TypeStrings[1] = "native";
TypeStrings[2] = "callback";
TypeStrings[3] = "function";
}
public ProfileReport(string file)
{
bool in_profile;
ProfileType type;
string cur_report;
XmlTextReader xml;
xml = new XmlTextReader(file);
xml.WhitespaceHandling = WhitespaceHandling.None;
m_Items = new List<ProfileItem>();
type = ProfileType.ProfType_Unknown;
in_profile = false;
cur_report = null;
while (xml.Read())
{
if (xml.NodeType == XmlNodeType.Element)
{
if (xml.Name.CompareTo("profile") == 0)
{
int t;
in_profile = true;
m_duration = Double.Parse(xml.GetAttribute("uptime"));
m_start_time = new DateTime(1970, 1, 1, 0, 0, 0);
t = Int32.Parse(xml.GetAttribute("time"));
m_start_time = m_start_time.AddSeconds(t);
}
else if (in_profile)
{
if (xml.Name.CompareTo("report") == 0)
{
cur_report = xml.GetAttribute("name");
if (cur_report.CompareTo("natives") == 0)
{
type = ProfileType.ProfType_Native;
}
else if (cur_report.CompareTo("callbacks") == 0)
{
type = ProfileType.ProfType_Callback;
}
else if (cur_report.CompareTo("functions") == 0)
{
type = ProfileType.ProfType_Function;
}
else
{
type = ProfileType.ProfType_Unknown;
}
}
else if (xml.Name.CompareTo("item") == 0 && cur_report != null)
{
ProfileItem item;
item = new ProfileItem();
item.name = xml.GetAttribute("name");
item.max_time = Double.Parse(xml.GetAttribute("maxtime"));
item.min_time = Double.Parse(xml.GetAttribute("mintime"));
item.num_calls = UInt32.Parse(xml.GetAttribute("numcalls"));
item.total_time = Double.Parse(xml.GetAttribute("totaltime"));
item.type = type;
m_Items.Add(item);
}
}
}
else if (xml.NodeType == XmlNodeType.EndElement)
{
if (xml.Name.CompareTo("profile") == 0)
{
break;
}
else if (xml.Name.CompareTo("report") == 0)
{
cur_report = null;
}
}
}
}
public double Duration
{
get
{
return m_duration;
}
}
public DateTime StartTime
{
get
{
return m_start_time;
}
}
public ProfileItem GetItem(int i)
{
return m_Items[i];
}
}
}
+20
View File
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace profviewer
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Main());
}
}
}
+80
View File
@@ -0,0 +1,80 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1EE11F57-B933-4D06-B0E6-EAFB60ACAC73}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>profviewer</RootNamespace>
<AssemblyName>profviewer</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Comparators.cs" />
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="ProfReport.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<SubType>Designer</SubType>
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "profviewer", "profviewer.csproj", "{1EE11F57-B933-4D06-B0E6-EAFB60ACAC73}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1EE11F57-B933-4D06-B0E6-EAFB60ACAC73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1EE11F57-B933-4D06-B0E6-EAFB60ACAC73}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1EE11F57-B933-4D06-B0E6-EAFB60ACAC73}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1EE11F57-B933-4D06-B0E6-EAFB60ACAC73}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,73 @@
<?php
class ProfReport
{
public $time;
public $uptime;
public $items = array();
}
class ProfReportParser
{
private $report;
private $curtype;
public $last_error;
public function Parse($file)
{
$this->report = FALSE;
$this->curtype = FALSE;
if (($contents = file_get_contents($file)) === FALSE)
{
$this->last_error = 'File not found';
return FALSE;
}
$xml = xml_parser_create();
xml_set_object($xml, $this);
xml_set_element_handler($xml, 'tag_open', 'tag_close');
xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, false);
if (!xml_parse($xml, $contents))
{
$this->last_error = 'Line: ' . xml_get_current_line_number($xml) . ' -- ' . xml_error_string(xml_get_error_code($xml));
return FALSE;
}
return $this->report;
}
public function tag_open($parser, $tag, $attrs)
{
if ($tag == 'profile')
{
$this->report = new ProfReport();
$this->report->time = $attrs['time'];
$this->report->uptime = $attrs['uptime'];
}
else if ($tag == 'report')
{
$this->curtype = $attrs['name'];
}
else if ($tag == 'item')
{
if ($this->report === FALSE || $this->curtype === FALSE)
{
return;
}
$attrs['type'] = $this->curtype;
$this->report->items[] = $attrs;
}
}
public function tag_close($parser, $tag)
{
if ($tag == 'report')
{
$this->curtype = FALSE;
}
}
}
?>
+165
View File
@@ -0,0 +1,165 @@
#!/usr/bin/perl
our %arguments =
(
'config' => 'modules.versions',
'major' => '1',
'minor' => '0',
'revision' => '0',
'build' => undef,
'svnrev' => 'global',
'path' => '',
);
my $arg;
foreach $arg (@ARGV)
{
$arg =~ s/--//;
@arg = split(/=/, $arg);
$arguments{$arg[0]} = $arg[1];
}
#Set up path info
if ($arguments{'path'} ne "")
{
if (!(-d $arguments{'path'}))
{
die "Unable to find path: " . $arguments{'path'} ."\n";
}
chdir($arguments{'path'});
}
if (!open(CONFIG, $arguments{'config'}))
{
die "Unable to open config file for reading: " . $arguments{'config'} . "\n";
}
our %modules;
my $cur_module = undef;
my $line;
while (<CONFIG>)
{
chomp;
$line = $_;
if ($line =~ /^\[([^\]]+)\]$/)
{
$cur_module = $1;
next;
}
if (!$cur_module)
{
next;
}
if ($line =~ /^([^=]+) = (.+)$/)
{
$modules{$cur_module}{$1} = $2;
}
}
close(CONFIG);
#Copy global configuration options...
if (exists($modules{'PRODUCT'}))
{
if (exists($modules{'PRODUCT'}{'major'}))
{
$arguments{'major'} = $modules{'PRODUCT'}{'major'};
}
if (exists($modules{'PRODUCT'}{'minor'}))
{
$arguments{'minor'} = $modules{'PRODUCT'}{'minor'};
}
if (exists($modules{'PRODUCT'}{'revision'}))
{
$arguments{'revision'} = $modules{'PRODUCT'}{'revision'};
}
if (exists($modules{'PRODUCT'}{'svnrev'}))
{
$arguments{'svnrev'} = $modules{'PRODUCT'}{'svnrev'};
}
}
#Get the global SVN revision if we have none
my $rev;
if ($arguments{'build'} == undef)
{
$rev = GetRevision(undef);
} else {
$rev = int($arguments{'build'});
}
my $major = $arguments{'major'};
my $minor = $arguments{'minor'};
my $revision = $arguments{'revision'};
my $svnrev = $arguments{'svnrev'};
#Go through everything now
my $mod_i;
while ( ($cur_module, $mod_i) = each(%modules) )
{
#Skip the magic one
if ($cur_module eq "PRODUCT")
{
next;
}
#Prepare path
my %mod = %{$mod_i};
my $infile = $mod{'in'};
my $outfile = $mod{'out'};
if ($mod{'folder'})
{
if (!(-d $mod{'folder'}))
{
die "Folder " . $mod{'folder'} . " not found.\n";
}
$infile = $mod{'folder'} . '/' . $infile;
$outfile = $mod{'folder'} . '/' . $outfile;
}
if (!(-f $infile))
{
die "File $infile is not a file.\n";
}
my $global_rev = $rev;
my $local_rev = GetRevision($mod{'folder'});
if ($arguments{'svnrev'} eq 'local')
{
$global_rev = $local_rev;
}
#Start rewriting
open(INFILE, $infile) or die "Could not open file for reading: $infile\n";
open(OUTFILE, '>'.$outfile) or die "Could not open file for writing: $outfile\n";
while (<INFILE>)
{
s/\$PMAJOR\$/$major/g;
s/\$PMINOR\$/$minor/g;
s/\$PREVISION\$/$revision/g;
s/\$GLOBAL_BUILD\$/$rev/g;
s/\$LOCAL_BUILD\$/$local_rev/g;
print OUTFILE $_;
}
close(OUTFILE);
close(INFILE);
}
sub GetRevision
{
my ($path)=(@_);
my $rev;
if (!$path)
{
$rev = `svnversion --committed`;
} else {
$rev = `svnversion --committed $path`;
}
if ($rev =~ /exported/)
{
die "Path specified is not a working copy\n";
} elsif ($rev =~ /(\d+):(\d+)/) {
$rev = int($2);
} elsif ($rev =~ /(\d+)/) {
$rev = int($1);
} else {
die "Unknown svnversion response: $rev\n";
}
return $rev;
}