falko-hartmann.de

Black Knight's Res Creator v1.1 (10.05.2005)

Beschreibung

Valve hat im Server eine Methode implementiert, mit der neben der eigentlichen Map auch zugehörige Dateien nachgeladen werden können. Dies betrifft insbesondere spezielle Wad-Dateien etc., die für das Spielen einer Map notwendig sind und beim Mapchange vom Client geladen werden müssen.

Auf Grund ihrer Anlage sind die sogenannten Res-Files komplett mapspezifisch, was bedeutet, dass es keine Standard-Res-Datei gibt, die für alle Maps gilt.

Viele Plugins für Admin Mod oder andere Metamod-Plugins nutzen eigene Sounds oder eigene Dateien. Diese müssen jedoch auf jeder Map geladen werden. Daher muss man in der Regel ALLE Res-Dateien editieren, was mit großem Arbeitsaufwand verbunden ist, insbesondere, wenn man viele Maps hat. Die Installation von Plugins mit eigenen Dateien ist daher sehr zeitaufwändig.

Die Idee war daher ein Plugin zu schreiben, das diese Dateien automatisch erstellt.

Features:


Download

plugin_bk_res


Installation

  1. Kompilieren des Plugins
  2. Installation des Plugins (WICHTIG: plugin_bk_res MUSS das ALLERLETZTE PLUGIN in der Liste sein, um einwandfrei zu funktionieren!!!)
  3. Erstelle ein Verzeichnis "addons/adminmod/config/res"
  4. Mapchange

Befehle

Für die Befehle braucht Ihr das Recht 512!

admin_res_refresh <Mapname>:
Erneuert die Res-Dateien aller Maps aus der Mapliste. Wenn ein Mapname angegeben wurde, wird nur die Res-Datei dieser Map erneuert. Man muss diesen Befehl jedes Mal durchführen, wenn man Änderungen an den Res-Dateien im Ordner "addons/adminmod/config/res" vorgenommen hat.
admin_res_maps <Mapliste>:
Standardmäßig erstellt das Plugin Res-Dateien für alle Maps, die in der mapcycle.txt gefunden wurden. Man kann seine eigene Liste mittels einer anderen Datei erstellen. Einzige Voraussetzung ist, dass sie genauso aufgebaut ist, wie die mapcycle.txt und alle Maps berücksichtigt, für die Res-Dateien erstellt werden sollen. Der Befehl setzt die Mapdatei oder gibt den aktuellen Wert zurück, falls keine Mapdatei spezifiziert wurde.

Konfiguration

Die einzelnen mapspezifischen Res-Dateien sind in das Verzeichnis addons/adminmod/config/res (z.B. fy_iceworld.res) zu verschieben. In diesen Res-Dateien sollten lediglich die mapspezifischen Dateien zu finden sein, die für das Spielen der Map unabdingbar sind (Keine Dateien von Plugins).

Für Res-Dateien für Plugins ist eine default.res (mittels Texteditor) zu erstellen und die Dateien einzufügen, die auf jeder Map benötigt werden.

Falls alles geklappt sollten die Res-Dateien im "maps" Verzeichnis zu finden sein.

Für Programmierer von Plugins mit Res-Dateien kann plugin_bk_res auch direkt ausgeführt werden.

Füge zur plugin_init() hinzu:

plugin_registercmd("res_refresh","res_refresh",ACCESS_CONSOLE,"");

Erstelle eine Funktion res_refresh():

public res_refresh(HLCommand,HLData,HLUserName,UserIndex){

	return PLUGIN_CONTINUE;
}

In dieser Funktionen sollten alle Dateien weitergeleitet werden, die von Deinem Plugin benötigt werden, z.B.:

public res_refresh(HLCommand,HLData,HLUserName,UserIndex){
	plugin_exec("res_add","sound/testwavplugin1.wav");
	plugin_exec("res_add","sound/testwavplugin2.wav");
	plugin_exec("res_add","sound/testwavplugin3.wav");
	return PLUGIN_CONTINUE;
}

Das ist es schon. Man kann auch die Erneuerung aus dem eigenen Plugin aus aktivieren, indem man admin_res_refresh mittels plugin_exec() ausführt. Auf diese Weise führt plugin_bk_res die res_refresh Funktion automatisch aus.


Quellcode

plugin_bk_res.sma:

#include <core> 
#include <console> 
#include <string> 
#include <admin> 
#include <adminlib>
#include <plugin>
 
new STRING_VERSION[MAX_DATA_LENGTH] = "1.1";
new g_sMap[MAX_DATA_LENGTH]="";
 
/* Check whether vault.ini exists */
is_vaultfile_set(){
	new vault[MAX_DATA_LENGTH];
	getstrvar("admin_vault_file",vault,MAX_DATA_LENGTH);
	if(streq(vault,"0") || strlen(vault)==0){
		if(getvar("admin_debug")>0){
			log("[BK_RES] No vault file defined.");
		}
		return 0;
	}
	return 1;
}
 
/* Define vault.ini */
define_vaultfile(){
	new sPath[MAX_DATA_LENGTH];
	getstrvar("amv_default_config_dir",sPath,MAX_DATA_LENGTH);
	snprintf(sPath,MAX_DATA_LENGTH,"%s/vault.ini",sPath);
	setstrvar("admin_vault_file",sPath);
	reload();
	if(getvar("admin_debug")>0){
		log("[BK_RES] Defined vault.ini myself.");
	}
}
 
/* Let's check, whether we should only refresh one map or all */
moremaps(sMapsFile[]){
	if(strlen(g_sMap)!=0){
		return 1;
	}
	else{
		get_vaultdata("BK_RES_MAPS",sMapsFile,MAX_DATA_LENGTH);
		/* This shouldn't happen and would spam the logs a bit, but better than an endless loop in the for-loop */
		if(!fileexists(sMapsFile)){
			log("[BK_RES] Defined mapsfile does not exist. Check admin_res_maps!");
			return 0;
		}
	}
	return filesize(sMapsFile,lines);
}
 
/* Just append the data of one file to another */
add_res_data(sMap[],sMap2[]){
	new iLines;
	new i;
	new sLine[MAX_DATA_LENGTH];
 
	if(fileexists(sMap)){
		iLines=filesize(sMap,lines);
		for(i=1;i<=iLines;i++){
			readfile(sMap,sLine,i,MAX_DATA_LENGTH);
			writefile(sMap2,sLine,-1);
		}
		return 1;
	}
	return 0;
}
 
/* Adding file to res-file, executed by external plugins */
public res_add(HLCommand,HLData,HLUserName,UserIndex){
	new sMapsFile[MAX_DATA_LENGTH];
	new sMap[MAX_DATA_LENGTH];
	new sMapRes[MAX_DATA_LENGTH];
	new sLine[MAX_DATA_LENGTH];
	new iLines;
	new i;
 
	/* sLine should now include the new res file entry */
	convert_string(HLData,sLine,MAX_DATA_LENGTH);
 
	/* Now we check whether the file exists at all */
	if(!fileexists(sLine)){
		snprintf(sLine,MAX_TEXT_LENGTH,"[BK_RES] File %s does not exist on server.",sLine);
		log(sLine);
		return PLUGIN_HANDLED;
	}
 
	/* Let's check, whether we should only refresh one map or all */
	iLines=moremaps(sMapsFile);
 
	if(!iLines){
		return PLUGIN_HANDLED;
	}
 
	/* Adding entry to res file */
	for(i=1;i<=iLines;i++){
		if(strlen(g_sMap)!=0){
			strcpy(sMap,g_sMap,MAX_DATA_LENGTH);
		}
		else{
			readfile(sMapsFile,sMap,i,MAX_DATA_LENGTH);
		}
		if(strlen(sMap)!=0){
			snprintf(sMapRes,MAX_DATA_LENGTH,"maps/%s.res",sMap);
			writefile(sMapRes,sLine,-1);
		}
	}
 
	return PLUGIN_HANDLED;
}
 
/* This function is for adding map specific data and/or default data to the res file(s). */
public res_refresh(HLCommand,HLData,HLUserName,UserIndex){
	new sMap[MAX_DATA_LENGTH];
	new sMapDefault[MAX_DATA_LENGTH];
	new sMapsFile[MAX_DATA_LENGTH];
	new sMapRes[MAX_DATA_LENGTH];
	new sPath[MAX_DATA_LENGTH];
	new iLines;
	new i;
 
	/* Let's check, whether we should only refresh one map or all */
	iLines=moremaps(sMapsFile);
 
	/* exit, if there is something wrong */
	if(!iLines){
		return PLUGIN_HANDLED;
	}
 
	getstrvar("amv_default_config_dir",sPath,MAX_DATA_LENGTH);
	snprintf(sMapDefault,MAX_DATA_LENGTH,"%s/res/default.res",sPath);
 
	for(i=1;i<=iLines;i++){
		if(strlen(g_sMap)!=0){
			strcpy(sMap,g_sMap,MAX_DATA_LENGTH);
		}
		else{
			readfile(sMapsFile,sMap,i,MAX_DATA_LENGTH);
		}
		if(strlen(sMap)!=0 && sMap[0]!='/' && sMap[0]!='#' && sMap[0]!=';'){
			/* We like to add any map specific data to the res file */ 
			snprintf(sMapRes,MAX_DATA_LENGTH,"maps/%s.res",sMap); //The res file
			snprintf(sMap,MAX_DATA_LENGTH,"%s/res/%s.res",sPath,sMap); //The map specific res file
			add_res_data(sMap,sMapRes);
 
			/* Of course, we also want to add some default data for all maps, if it exists */
			add_res_data(sMapDefault,sMapRes);
		}
	}
 
	strinit(g_sMap);
	log("[BK_RES] Res files created!");
 
	return PLUGIN_HANDLED;
}
 
/* Starting the recreation of the res files for all maps or a specific map */
public admin_res_refresh(HLCommand,HLData,HLUserName,UserIndex){
	new sMap[MAX_DATA_LENGTH];
	new iLines,i;
	new sMapsFile[MAX_DATA_LENGTH];
 
	/* sMap should now include the map to be renewed or nothing */
	convert_string(HLData,sMap,MAX_DATA_LENGTH);
 
	/* Let's check, whether we should only refresh one map or all */
	iLines=moremaps(sMapsFile);
 
	/* exit, if there is something wrong */
	if(!iLines){
		return PLUGIN_HANDLED;
	}
 
	/* Delete those files we want to recreate at first*/
	for(i=1;i<=iLines;i++){
		if(strlen(sMap)!=0){
			strcpy(g_sMap,sMap,MAX_DATA_LENGTH);
		}
		else{
			readfile(sMapsFile,sMap,i,MAX_DATA_LENGTH);
		}
		if(strlen(sMap)!=0 && sMap[0]!='/' && sMap[0]!='#' && sMap[0]!=';'){
			snprintf(sMap,MAX_DATA_LENGTH,"maps/%s.res",sMap);
			if(fileexists(sMap)){
				deletefile(sMap);
			}
		}
		strinit(sMap);
	}
 
	/* Ok let's see, which plugin has something to tell ;-) */
	plugin_exec("res_refresh","");
 
	return PLUGIN_HANDLED;
}
 
/* Defining the file with the maps for which res files should be created */
public admin_res_maps(HLCommand,HLData,HLUserName,UserIndex){
	new sMapsFile[MAX_DATA_LENGTH];
	new sText[MAX_TEXT_LENGTH];
 
	/* Here we have most probably the maps file */
	convert_string(HLData,sMapsFile,MAX_DATA_LENGTH);
 
	/* At first we check, if a map is specified. If it isn't, we would return the current value */
	if(!strlen(sMapsFile)){
		get_vaultdata("BK_RES_MAPS",sMapsFile,MAX_DATA_LENGTH);
		snprintf(sText,MAX_TEXT_LENGTH,"Maps file is: %s",sMapsFile);
		selfmessage(sText);
		return PLUGIN_HANDLED;
	}
 
	/* Secondly, we check whether the specified file exists. If it does exist, we would change the the setting and return the new value */
	if(fileexists(sMapsFile)){
		set_vaultdata("BK_RES_MAPS",sMapsFile);
		snprintf(sText,MAX_TEXT_LENGTH,"Maps file is now: %s",sMapsFile);
		selfmessage(sText);
		return PLUGIN_HANDLED;
	}
 
	/* If everything fails, the file is non-existant, so we inform the user that he/she made a mistake */
	snprintf(sText,MAX_TEXT_LENGTH,"ERROR: Specified maps file %s does not exist!",sMapsFile);
	selfmessage(sText);	
 
	return PLUGIN_HANDLED;
}
 
/* Init the plugin */
public plugin_init() {
	new sMaps[MAX_DATA_LENGTH];
	/* Plugin Registrierung */
	plugin_registerinfo("BK Res","Managing Res-Files",STRING_VERSION);
	plugin_registercmd("res_refresh","res_refresh",ACCESS_CONFIG,"");
	plugin_registercmd("res_add","res_add",ACCESS_CONFIG,"");
	plugin_registercmd("admin_res_refresh","admin_res_refresh",ACCESS_CONFIG,"admin_res_refresh [mapname]: Regenerates res-files of all or a certain map.");
	plugin_registercmd("admin_res_maps","admin_res_maps",ACCESS_CONFIG,"admin_res_maps <maplist>: Defines the file including the maps for which res-files should be created.");
 
	/* vault.ini check und ggf. definieren */
	if(!is_vaultfile_set()){
		define_vaultfile();
	}
 
	/* Install plugin with initial values */
	if(!get_vaultdata("BK_RES_MAPS",sMaps,MAX_DATA_LENGTH)){
		getstrvar("mapcyclefile",sMaps,MAX_DATA_LENGTH);
		set_vaultdata("BK_RES_MAPS",sMaps);
		set_vaultnumdata("BK_RES_NO",0);
		if(getvar("admin_debug")>0){
			log("[BK_RES] Installed! Using mapcycle for res file creation.");
		}
	}
 
 	return PLUGIN_CONTINUE; 
}