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:
@@ -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)
|
||||
Executable
+16
@@ -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.
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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("")]
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
OutputBase = /home/dvander/bin
|
||||
SourceBase = /home/dvander/sourcemod/trunk
|
||||
BuilderPath = /usr/bin/make
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
OutputBase = c:\real\done
|
||||
SourceBase = r:\sourcemod\trunk
|
||||
BuilderPath = C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
g++ -I../../core ../../core/sm_crc32.cpp main.cpp -ocrc32
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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_
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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_
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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_
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")]
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+243
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user