
Este proyecto se crea con el objetivo de reemplazar el steam_api.dll original de Steam con este y, por lo tanto, emulando una conexión para poder jugar en el modo LAN. Este no es un envoltorio de Steamworks como Steamworks.Net o Facepunch . El proyecto está en una etapa inicial, por lo que aún no es funcional para algunos juegos.
Hace algún tiempo no he podido actualizar el repositorio debido a problemas personales, por lo que aquellos que desean colaborar con el desarrollo son bienvenidos

Al compilar el proyecto, se generan dos carpetas (x64 y x86) que contienen la DLL para una plataforma de destino diferente, en el caso de X64, debe cambiar el nombre del archivo a Steam_api64.dll, para emular la conexión a Steam de un juego, debe reemplazar el DLL con el que contiene el juego. En caso de que el motor del juego sea Unity, puede cambiar el nombre de DLL a Csteamworks.dll y reemplazarlo.
Para usar el cliente, simplemente necesita agregar el juego y configurar el APPID. El cliente está actualmente en desarrollo.
? Root client folder
├──? x64 // The x64 version of the SteamAPI dll that will be injected
├──? x86 // The x64 version of the SteamAPI dll that will be injected
└──? Data
├──? Assemblies // Contains client libraries (Including cefsharp api or gecko)
├──? Images // Contains app cache and avatar images
├──? Injector // Contains the DLL injectors
├──? www // Contains the web files
├──? Storage // Contains stats and achievements files
| └──? Remote // Contains game files
└──? Games.bin // Stored game list
? Root server folder
└──? Data
├──? Assemblies // Contains server libraries
├──? Images // Contains app cache and avatar images
├──? MongoDB // Contains local MongoDB server
└──? Storage // Contains some server files
User Stats manager Save and Load user stats from local folder.
Achievements manager Save and Load user achievements from local folder.
CSteamworks emulation Rename the emu to CSteamworks.dll to emulate them.
Supported Game Engines Works with multiple game engines like Source 2, Unity 3D etc.
Network communication Network communication between clients through a configurable port.
Overlay External Overlay for steam and game messages.
DLC Unlock all downloaded DLCs.
Avatar support Load avatar from file (Avatar.jpg) inside SKYNET folder and share it through the network.
Plugin system Load external plugin to communicate with the emu.
In game voice Fully functional voice system
Implementación del sistema de devolución de llamada.
SteamInternal_Contextinit en X86 juegos
Cuando la opción de registro de archivo SI habilitado en la configuración, se creará un archivo de registro dentro de la carpeta "Carpeta de juego root/skynet" con el siguiente nombre [SKYNET] steam_api.log
El sistema de complementos se desarrolla para establecer una comunicación entre el juego y el coordinador del juego, el siguiente ejemplo muestra un complemento básico.
Interfaz para el complemento del coordinador de juegos:
namespace SKYNET . Plugin
{
public interface IGameCoordinatorPlugin
{
uint Initialize ( ) ;
void MessageFromGame ( byte [ ] bytes ) ;
EventHandler < Dictionary < uint , byte [ ] > > IsMessageAvailable { get ; set ; }
}
}Ejemplo de complemento del coordinador del juego:
namespace SKYNET . Plugin
{
public class Dota2GameCoordinator : IGameCoordinatorPlugin
{
private uint AppID = 570 ;
public EventHandler < Dictionary < uint , byte [ ] > > IsMessageAvailable { get ; set ; }
public uint Initialize ( )
{
// TODO: Initialize all Game coordinator class
return AppID ;
}
public void MessageFromGame ( byte [ ] bytes )
{
// Process message from game
uint MsgType = MsgUtil . GetGCMsg ( new MemoryStream ( bytes ) . ReadUInt32L ( ) ) ;
IPacketGCMsg packetGCMsg = MsgUtil . GetPacketGcMsg ( MsgType , bytes ) ;
// TODO: Process GC message
}
public void SendPacketToGame ( uint msgType , byte [ ] packet )
{
Dictionary < uint , byte [ ] > message = new Dictionary < uint , byte [ ] > ( ) ;
message . Add ( msgType , packet ) ;
IsMessageAvailable ? . Invoke ( this , message ) ;
}
public void SendPacketToGame ( Dictionary < uint , byte [ ] > messages )
{
IsMessageAvailable ? . Invoke ( this , messages ) ;
}
}
}