Skip to content

Instantly share code, notes, and snippets.

@aspann

aspann/Civ5XP.c Secret

Last active January 9, 2019 23:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aspann/43b5c514f63aab5b011ec06c60b15bee to your computer and use it in GitHub Desktop.
Save aspann/43b5c514f63aab5b011ec06c60b15bee to your computer and use it in GitHub Desktop.
linux steam Civilzation 5 wrapper. (fix for bink-video issue and multi-core support)
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
char *rBin = "Civ5XP.run";
char curDir[PATH_MAX];
char civDir[PATH_MAX];
bool _logging;
bool _recover;
bool _debug;
int hasSuffix(char *string , char *suffix, bool recover) {
char suff[PATH_MAX];
strcpy(suff, suffix);
string = strrchr(string, '.');
if (recover == true)
strcat(suff, "_bak");
if(string != NULL)
return(strcmp(string, suff));
return(-1);
}
void fixMov(char *path, bool recover) {
DIR *d = opendir(path);
if(d==NULL) return;
struct dirent *dir;
while ((dir = readdir(d)) != NULL) {
if(dir->d_type != DT_DIR) { // file
if (hasSuffix(dir->d_name, ".mov", recover) == 0) {
char message[10] = "disabled";
char srcFile[PATH_MAX];
char dstFile[PATH_MAX];
sprintf(srcFile, "%s/%s", path, dir->d_name);
strcpy(dstFile, srcFile);
strcat(dstFile, "_bak");
if (recover == true) {
strcpy(message, "recovered");
dstFile[strlen(srcFile)-8] = 0;
}
// renaming files
if (rename(srcFile, dstFile) == 0 && (_debug || _logging)) {
printf("%s (%s)\n", dir->d_name, message);
}
}
} else if (dir->d_type == DT_DIR && strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0) { // dir
char d_path[PATH_MAX];
sprintf(d_path, "%s/%s", path, dir->d_name);
fixMov(d_path, recover); // recursion
}
}
closedir(d);
}
void createAppId(char *dir) {
char file[PATH_MAX];
strcpy(file, dir);
strcat(file, "/steam_appid.txt");
FILE *fp;
fp = fopen(file, "rb+");
if(fp == NULL) {
fp = fopen(file, "wb");
}
fprintf(fp, "8930"); // saving appid
fclose(fp);
}
int main(int argc, char **argv) {
char runBin[PATH_MAX];
char runCmd[PATH_MAX];
// parse arguments
if (argc > 1) {
for(int i = 1; i < argc; i++) {
if (strchr(argv[i], 'r') != NULL) {
_recover = true;
}
if (strchr(argv[i], 'd') != NULL) {
_debug = true;
}
if (strchr(argv[i], 'l') != NULL) {
_logging = true;
}
}
}
// getting home (setting default)
strcpy(civDir, getenv("HOME"));
strcat(civDir, "/.local/share/Steam/steamapps/common/Sid Meier's Civilization V");
// setting run command
if (sysconf(_SC_NPROCESSORS_ONLN) > 8)
strcpy(runCmd, "numactl --physcpubind=+0-7");
sprintf(runCmd, "%s ./%s", runCmd, rBin);
// getting pwd
strcpy(curDir, getenv("PWD"));
strcpy(runBin, curDir);
strcat(runBin, "/Civ5XP.run");
if (access(runBin, X_OK) != 0) {
// seems to be the civDirectory
strcpy(civDir, curDir);
strcpy(runBin, curDir);
strcat(runBin, "/Civ5XP.run");
if (access(runBin, X_OK) != 0) {
printf("File not executable: '%s'\n", runBin);
return(1);
}
if (_debug || _logging)
printf("Using autodetected directory: '%s'\n", civDir);
}
// info
if (_debug || _logging) {
printf("directory.....: '%s'\n", civDir);
printf("binary........: '%s'\n", rBin);
printf("recover.......: %s\n", _recover?"true":"false");
printf("run command...: '%s'\n", runCmd);
}
// fixing intro-movies
fixMov(civDir, false);
// fixing AppId (for standalone/LAN mode)
createAppId(civDir);
// real execution of original binary
int ret = system(runCmd);
// if recovery
if (_recover) {
fixMov(civDir, true);
}
return(ret);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment