Skip to content

Instantly share code, notes, and snippets.

@Kolesias123
Created December 5, 2013 23:25
Show Gist options
  • Select an option

  • Save Kolesias123/7815982 to your computer and use it in GitHub Desktop.

Select an option

Save Kolesias123/7815982 to your computer and use it in GitHub Desktop.
Transforma una solución de Visual Studio de Source SDK 2013 a VPC.
<?php
#######################################################
# Creación del VPC.
#######################################################
# El siguiente Script le permite transformar una solución
# de Visual Studio al formato VPC.
#
# Los archivos VPC (Valve Project Creator) permiten la
# creación de los archivos necesarios para compilar el juego
# según la plataforma que este usando.
#
# Windows: Generará .sln (Visual Studio)
# Linux: Generará cmake
# Mac: No tengo idea...
#
# https://developer.valvesoftware.com/wiki/Valve_Project_Creator
#######################################################
# Atención: El Script no es perfecto y necesita mejoras,
# no compile el archivo generado a menos que sea revisado
# posteriormente. (O contacte a Iván)
#######################################################
# Ruta de la aplicación.
define('DS', DIRECTORY_SEPARATOR);
# XML 2 ARRRAY
include './xml2array.php';
# Nombre de la solución.
$game = 'hl2mp';
$pre = 'APOCALYPSE';
$onlyGame = true; // true: No incluir los archivos base de InSource y HL2
# Ruta hacia la carpeta "game" del código fuente.
$srcPath = '..' . DS . 'src' . DS . 'game' . DS;
# Ruta hacia los archivos necesarios de la solución.
$server = $srcPath . 'server' . DS . 'server_' . $game . '.vcxproj.filters';
$client = $srcPath . 'client' . DS . 'client_' . $game . '.vcxproj.filters';
#########################################################################################
# DESDE AQUÍ NO EDITE NADA A MENOS QUE QUIERA DESTRUIR SU VALIOSO JUEGO. "hard-coded"
#
# El siguiente código ha sido escrito dura y directamente, no cambie absolutamente
# nada a menos que tenga una idea exacta de lo que hará y tenga conocimientos en:
#
# - Filtros de una solución de Visual Studio.
# - Sintaxis y funcionamiento de Valve Project Creator (VPC)
#
# En caso de que algo deje de funcionar porfavor contacte a Iván Bravo (ivan-bravo@infosmart.mx)
#
#########################################################################################
#
# Funciones
#
/**
* Devuelve la Indentación correcta.
*/
function ind($i)
{
if ( $i <= 0 )
return;
$result = '';
for ( $e = 1; $e <= $i; ++$e )
$result .= "\t";
return $result;
}
/**
* Devuelve el código VPC resultante de una carpeta.
* @param string $name Nombre de la carpeta.
* @param string $files Archivos dentro.
* @param integer $i [description]
*/
function MakeFolder($name, $files, $i = 1)
{
$result = ind($i) . '$Folder "' . $name . '"' . PHP_EOL;
$result .= ind($i) . '{' . PHP_EOL;
$result .= ProcessFiles($name, $files, $i);
$result .= ind($i) . '}' . PHP_EOL . PHP_EOL;
return $result;
}
/**
* Procesa los archivos dentro de una carpeta y devuelve el código VPC.
*
* @param string $from Carpeta origen.
* @param string $files Archivos a procesar.
* @param integer $i [description]
*/
function ProcessFiles($from, $files, $i)
{
# Resultado y carpetas que se deben ignorar.
$result = '';
$ignore = ['Navigation Mesh', 'temporary entities', 'Precompiled Header', 'game_controls', 'Sixense', 'Temporary Entities']; // Por el amor de Gaben, no ponga ningún archivo nuevo en estas carpetas.
global $onlyGame;
if ( $onlyGame )
{
$ignore[] = 'HL2 DLL';
$ignore[] = 'InSource';
}
# Examinamos cada archivo.
foreach ( $files as $key => $value )
{
# Es una carpeta que debe ignorarse.
if ( in_array($key, $ignore) )
continue;
# Realmente es un archivo.
if ( is_string($value) )
{
# Si viene del código fuente del motor, ignorar.
if ( $from == 'Source Files' )
continue;
# Creamos el código VPC
$value = str_replace('..\\..\\', '$SRCDIR\\', $value);
$result .= ind($i+1) . '$File' . "\t" . '"' . $value . '"' . PHP_EOL;
}
# Se trata de una subcarpeta.
else if ( is_array($value) AND !is_numeric($key) )
{
$result .= MakeFolder($key, $value, $i+1);
}
}
return $result;
}
/**
* Devuelve el código VPC del proyecto.
*
* @param array $data Información de carpetas y archivos de la solución.
*/
function MakeVPC($data)
{
# Resultado y carpetas que se deben ignorar.
$result = '';
$ignore = ['Header Files', 'Replay', 'Tools Framework', 'Tool Framework', 'VPC Scripts', 'Game Shared Header Files', 'game_controls Header Files', 'MP3', 'Public Header Files']; // Por el amor de Gaben, no ponga ningún archivo nuevo en estas carpetas.
foreach ( $data as $key => $value )
{
if ( in_array($key, $ignore) )
continue;
$result .= MakeFolder($key, $value);
}
return $result;
}
function ReadFilters($xml)
{
$result = [];
foreach ( $xml as $key => $odata )
{
# En estas secciones no hay información útil.
if ( $key == 0 OR $key == 1 OR $key == 4 OR $key == 6 )
continue;
$data = $odata['ClInclude'];
if ( !is_array($data) )
$data = $odata['ClCompile'];
if ( !is_array($data) )
$data = $odata['CustomBuild'];
# No hay informarción.
if ( !is_array($data) )
{
echo "Problema al leer los datos de la llave $key " . PHP_EOL;
continue;
}
# Examinamos cada archivo.
foreach ( $data as $mKey => $mData )
{
# Este es el archivo y su carpeta dentro de la solución.
$file = $mData['attr']['Include'];
$folder = $mData['Filter']['value'];
# Evitamos problemas con los \
$file = str_replace('\\', '\\\\', $file);
# ¿Sin carpeta?
if ( empty($folder) )
continue;
# Separamos las carpetas.
$e = explode('\\', $folder);
# Hay más de 1 carpeta, aquí debemos hacer algo especial...
if ( count($e) > 0 )
{
# @TODO: ¿Algo mejor?
$test = '["' . implode('"]["', $e) . '"][]';
eval("\$result$test = \"$file\";");
}
else
{
$result[$folder] = $file;
}
}
}
return $result;
}
#
# Cliente
#
# Leemos los filtros de la solución de Visual Studio.
$clientXML = xml2array( file_get_contents($client) );
$clientXML = $clientXML['Project']['ItemGroup'];
# Aquí se almacenaran las carpetas y archivos de tu juego.
$clientData = ReadFilters($clientXML);
# Leemos la base para el VPC final.
$clientVPC = file_get_contents('./base_client.vpc');
# Generamos el VPC del cliente.
$tmpVPC = MakeVPC($clientData);
# Reemplazamos algunas cosas...
$clientVPC = str_ireplace('{game}', $game, $clientVPC);
$clientVPC = str_ireplace('{preprocessor}', $pre, $clientVPC);
$clientVPC = str_ireplace('{vpc}', $tmpVPC, $clientVPC);
# Creamos el VPC.
$ready = file_put_contents('./vpc_result/client_' . $game . '.vpc', $clientVPC);
if ( !$ready )
exit('Ha ocurrido un problema al crear el VPC de cliente.');
#
# Servidor
#
# Leemos los filtros de la solución de Visual Studio.
$serverXML = xml2array( file_get_contents($server) );
$serverXML = $serverXML['Project']['ItemGroup'];
# Aquí se almacenaran las carpetas y archivos de tu juego.
$serverData = ReadFilters($serverXML);
# Leemos la base para el VPC final.
$serverVPC = file_get_contents('./base_server.vpc');
# Generamos el VPC del servidor.
$tmpVPC = MakeVPC($serverData);
# Reemplazamos algunas cosas...
$serverVPC = str_ireplace('{game}', $game, $serverVPC);
$serverVPC = str_ireplace('{preprocessor}', $pre, $serverVPC);
$serverVPC = str_ireplace('{vpc}', $tmpVPC, $serverVPC);
# Creamos el VPC.
$ready = file_put_contents('./vpc_result/server_' . $game . '.vpc', $serverVPC);
if ( !$ready )
exit('Ha ocurrido un problema al crear el VPC de servidor.');
echo 'Listo';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment