Ghost Recorder on 1.9.0

Сообщения
167
Реакции
32
Ошибка
In 1.8.2 this plugin is working well. But updating it to 1.9.0, plugin can not play recorded demo of the player. Demo is recorded without problems but it start playing it...any help to transfer the source code to working with updated amxmodx ?
ОС
Windows
Amx Mod X
AMX Mod X 1.9.0.5241 (http://www.amxmodx.org)
Authors:
	David "BAILOPAN" Anderson, Pavol "PM OnoTo" Marko
	Felix "SniperBeamer" Geyer, Jonny "Got His Gun" Bergstrom
	Lukasz "SidLuke" Wlasinski, Christian "Basic-Master" Hammacher
	Borja "faluco" Ferrer, Scott "DS" Ehlert
Compiled: Jan 30 2019 07:09:20
Built from: https://github.com/alliedmodders/amxmodx/commit/21100375
Build ID: 5241:21100375
Core mode: JIT+ASM32
C++
Билд
Protocol version 48
Exe version 1.1.2.7/Stdio (cstrike)
Exe build: 16:10:54 Aug 10 2018 (7960)
C++
ReGamedll
No ReGamedll
C++
Версия Metamod
Metamod v1.21-am  2013-03-15 (5:13)
by Will Day <.org>
   http://www.metamod.org/
compiled: Mar 15 2013, 15:20:21  (msc optimized)
C++
Список метамодулей
Currently loaded plugins:
      description      stat pend  file              vers      src  load  unlod
 [ 1] AMX Mod X        RUN   -    amxmodx_mm.dll    v1.9.0.5  ini  Start ANY  
 [ 2] RoundEndBlock    RUN   -    roundendblock_mm  v1.0      ini  ANY   ANY  
 [ 3] MySQL            RUN   -    mysql_amxx.dll    v1.9.0.5  pl1  ANY   ANY  
 [ 4] SQLite           RUN   -    sqlite_amxx.dll   v1.9.0.5  pl1  ANY   ANY  
 [ 5] Orpheu           RUN   -    orpheu_amxx.dll   v2.6.3    pl1  ANY   ANY  
 [ 6] Ham Sandwich     RUN   -    hamsandwich_amxx  v1.9.0.5  pl1  ANY   ANY  
 [ 7] Engine           RUN   -    engine_amxx.dll   v1.9.0.5  pl1  ANY   ANY  
 [ 8] FakeMeta         RUN   -    fakemeta_amxx.dl  v1.9.0.5  pl1  ANY   ANY  
 [ 9] CStrike          RUN   -    cstrike_amxx.dll  v1.9.0.5  pl1  ANY   ANY  
 [10] Fun              RUN   -    fun_amxx.dll      v1.9.0.5  pl1  ANY   ANY  
10 plugins, 10 running
C++
Список плагинов
Currently loaded plugins:
       name                    version     author            file             status   
 [  1] Custom Player Air Acce  2.1         Arkshine / juice  custom_aa.amxx   running  
 [  2] Amx_points              1.0         JocA              amx_points.amxx  running  
 [  3] Shop menu               1.0         JocA              compshop.amxx    running  
 [  4] Timer Deathrun          1.0         Jo`cA               comptimer.amxx   debug    
 [  5] ProKreedz               2.31        nucLeaR & p4ddY   prokreedz.amxx   paused   
 [  6] New Plug-In             1.0         Johan             cup_votemap.amx  debug    
 [  7] PrimeKZ                 1.0         JocA              primekz.amxx     running  
 [  8] Admin Base              1.9.0.5241  AMXX Dev Team     admin.amxx       running  
 [  9] Admin Commands          1.9.0.5241  AMXX Dev Team     admincmd.amxx    running  
 [ 10] Ghost Recorder          0.24        TeddyDesTodes     record.amxx      running  
 [ 11] Admin Help              1.9.0.5241  AMXX Dev Team     adminhelp.amxx   running  
 [ 12] Slots Reservation       1.9.0.5241  AMXX Dev Team     adminslots.amxx  running  
 [ 13] unknown                 unknown     unknown           progres_bar.amx  paused   
 [ 14] Multi-Lingual System    1.9.0.5241  AMXX Dev Team     multilingual.am  running  
 [ 15] Menus Front-End         1.9.0.5241  AMXX Dev Team     menufront.amxx   running  
 [ 16] Commands Menu           1.9.0.5241  AMXX Dev Team     cmdmenu.amxx     running  
 [ 17] Players Menu            1.9.0.5241  AMXX Dev Team     plmenu.amxx      running  
 [ 18] Teleport Menu           1.9.0.5241  AMXX Dev Team     telemenu.amxx    running  
 [ 19] Maps Menu               1.9.0.5241  AMXX Dev Team     mapsmenu.amxx    running  
 [ 20] Plugin Menu             1.9.0.5241  AMXX Dev Team     pluginmenu.amxx  running  
 [ 21] Admin Chat              1.9.0.5241  AMXX Dev Team     adminchat.amxx   running  
 [ 22] Anti Flood              1.9.0.5241  AMXX Dev Team     antiflood.amxx   running  
 [ 23] Scrolling Message       1.9.0.5241  AMXX Dev Team     scrollmsg.amxx   running  
 [ 24] Admin Votes             1.9.0.5241  AMXX Dev Team     adminvote.amxx   running  
 [ 25] Pause Plugins           1.9.0.5241  AMXX Dev Team     pausecfg.amxx    running  
 [ 26] Stats Configuration     1.9.0.5241  AMXX Dev Team     statscfg.amxx    running  
26 plugins, 25 running
C++
Автор плагина
TeddyDesTodes
Версия плагина
Ghost Recorder
Исходный код
/**
 *	Ghost Recorder by TeddyDesTodes
 *  
 *  CVars
 * 		recorder_maxsize  <size in kb>  Default:2048 set to 0 to make unlimited files
 * 		recorder_ignore_velocity  <0|1>  Default:0(off)  Ignore velocity at playback, this should stop weird movement but Ghost will look a bit laggy
 * 
 *  Thx to Empґ for helping with casting
 * 
 * 	How to:
 *      copy recorder.amxx to addons/amxmodx/plugins/
 * 		insert recorder.amxx into plugins.ini
 * 		create a folder called "kzrecord/" in your mod folder
 * 
 *  Ingame Commands:
 * 		say /demomenu        opens the menu
 * 
 *  Defines:
 * 		MAXSLOTS = Maximum saveslots per player and map maximum 9
 * 		SAVEPATH = Folder for storing ghosts (dont forget to create it)
 * 		RECLIMITER = Limits the amount of data written to file higher means less size but less accurate results should be something between 0.05 and 0.01
 * 		FILEVERSION = DO NOT CHANGE!!!
 * 
 **/


#include <amxmodx>
#include <fakemeta>
#include <fakemeta_util>

#define PLUGIN	"Ghost Recorder"
#define AUTHOR	"TeddyDesTodes"
#define VERSION	"0.24"
#define PREFIX	"Recorder"

#define FILEVERSION 24
#define MAXPLAYERS 33
#define RECLIMITER 0.03
#define MAXSLOTS 6
#define SAVEPATH "addons/amxmodx/data/record/"

#define RECORDKEYS MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_0
#define SLOTKEYS MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_9|MENU_KEY_0
new g_FileHandler[MAXPLAYERS]
new g_MapName[33],g_HostName[33]
new g_SteamId[MAXPLAYERS][35]
new g_syncHud
new g_CVar_maxsize,g_CVar_igveloc
new Float:g_LastThink[MAXPLAYERS]
new g_Rate[MAXPLAYERS]
new Float:g_LastAngle[MAXPLAYERS][3]
new Float:g_LastOrigin[MAXPLAYERS][3]
new Float:g_LastVelocity[MAXPLAYERS][3]
new g_isRecording[MAXPLAYERS],g_isPause[MAXPLAYERS],g_SaveSlot[MAXPLAYERS],g_MenuOpen[MAXPLAYERS],g_Ghost[MAXPLAYERS],g_GhostWeapon[MAXPLAYERS]
new g_Rec_Playername[MAXPLAYERS][33],g_Rec_Steamid[MAXPLAYERS][35],g_Rec_HostName[MAXPLAYERS][33],g_Rec_Time[MAXPLAYERS][20],g_Rec_Bytes[MAXPLAYERS][2];
new g_RenderFxName[][] = {"Normal","Hologram","Glow"}
new g_RenderColorName[][] = {"White","Green","Yellow","Blue","Red"}
new g_RenderColors[][] = {{255,255,255},{0,255,0},{255,255,0},{0,0,255},{255,0,0}}
new g_RenderName[][] = {"None","Alpha","Add"}
new g_RenderAmount[MAXPLAYERS],g_RenderType[MAXPLAYERS],g_RenderFx[MAXPLAYERS],g_RenderColor[MAXPLAYERS],g_GhostOwnerOnly[MAXPLAYERS]
new g_Offset[MAXPLAYERS],g_Next[MAXPLAYERS],g_ForeignFile[MAXPLAYERS][128];
public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_forward(FM_Think,"fm_ghost_think",0)
	register_forward(FM_PlayerPostThink,"fm_plr_prethink",0)
	register_forward(FM_AddToFullPack, "addToFullPack", 1);
	register_clcmd("say /demomenu","menu_show")
	register_clcmd("say /test","choose_slot")
	register_menucmd(register_menuid("Demo Recorder"), RECORDKEYS, "menuhandler")
	register_menucmd(register_menuid("Slot Chooser"), SLOTKEYS, "slothandler")
	register_menucmd(register_menuid("Foreign Loader"), SLOTKEYS, "loaderhandler")
	register_menucmd(register_menuid("Render Chooser"), SLOTKEYS, "renderhandler")
	register_cvar("ghost_recorder", VERSION, FCVAR_SERVER);
	g_syncHud = CreateHudSyncObj()
	//Cvars
	g_CVar_maxsize = register_cvar("recorder_maxsize","2048")
	g_CVar_igveloc = register_cvar("recorder_ignore_velocity","0")
	//create dir if needed
	if(!dir_exists(SAVEPATH)){
		log_amx("Save dir doe not exsit, creating for you =)")
		if(mkdir(SAVEPATH) != 0){
			log_amx("Couldn't create dir do it yourself!")
		}
	}
	//get mapname
	get_mapname(g_MapName,32);
	//get hostname
	get_cvar_string("hostname",g_HostName,32);
	//start hud task
	set_task(1.0,"hud",_,_,_,"b",0)
}
public client_putinserver(id){
	g_FileHandler[id] = 0
	g_isRecording[id] = 0
	g_isPause[id] = 0
	g_LastThink[id] = get_gametime()
	g_SaveSlot[id] = 0
	g_RenderAmount[id] = 120
	g_RenderType[id] = 1
	g_RenderFx[id] = 1
	g_RenderColor[id] = 0
	g_Ghost[id] = 0
	g_GhostWeapon[id] = 0
	g_Offset[id] = 0
	g_GhostOwnerOnly[id] = 1
	g_Next[id] = 0
}
public client_authorized(id){
	get_user_authid(id,g_SteamId[id][0],34)
	replace_all(g_SteamId[id][0],34,":","_")
}
public plugin_end(){
	for(new i = 0; i < MAXPLAYERS; i++){
		if(g_FileHandler[i] != 0){
			fclose(g_FileHandler[i])
			g_FileHandler[i] = 0
		}
	}
}
public client_disconnect(id){
	if(g_FileHandler[id] != 0){
		fclose(g_FileHandler[id]);
		g_FileHandler[id] = 0;
	}
}
public hud(){
	static filename[128],size
	for(new i = 0; i< MAXPLAYERS; i++){
		if(is_user_connected(i) && g_isRecording[i]){
			get_filename(i,g_SaveSlot[i],filename)
			size = filesize(filename)/1024
			set_hudmessage(255,0,0,-0.9,-0.9,_,_,0.4,0.3,0.3);
			if(get_pcvar_num(g_CVar_maxsize) > 0){
				ShowSyncHudMsg(i,g_syncHud,"[ REC %d/%d kb (%d byte/s) ]",size,get_pcvar_num(g_CVar_maxsize),g_Rate[i]);
			}else{
				ShowSyncHudMsg(i,g_syncHud,"[ REC %d (%d byte/s) ]",size,get_pcvar_num(g_CVar_maxsize),g_Rate[i]);
			}
		}else if(is_user_connected(i) && g_isRecording[i] == 0 && g_FileHandler[i] != 0){
			set_hudmessage(255,255,255,-0.9,-0.9,_,_,0.4,0.3,0.3);
			if(g_isPause[i] == 1){
				ShowSyncHudMsg(i,g_syncHud,"[ PAUSE ]^n(%s(%s) on %s@%s %d%% )",g_Rec_Playername[i],g_Rec_Steamid[i],g_Rec_HostName[i],g_Rec_Time[i],(g_Rec_Bytes[i][1]*100)/g_Rec_Bytes[i][0]);
			}else{
				ShowSyncHudMsg(i,g_syncHud,"[ PLAY ]^n%(%s(%s) on %s@%s %d%% )",g_Rec_Playername[i],g_Rec_Steamid[i],g_Rec_HostName[i],g_Rec_Time[i],(g_Rec_Bytes[i][1]*100)/g_Rec_Bytes[i][0]);
			}
		}
	}
}
public menu_show(id){
	g_MenuOpen[id] = 1;
	new menu[256],filename[128]
	new size[10]
	new playpause[3],stop[3],record[19],choose[3],slot[2]
	get_filename(id,g_SaveSlot[id],filename)
	if(file_exists(filename)){
		formatex(size,9,"%dKb",file_size(filename)/1024)
		formatex(playpause,2,"\y")
	}else{
		formatex(size,9,"FREE")
		formatex(playpause,2,"\d")
	}
	if(g_isRecording[id]){
		formatex(playpause,2,"\d")
		formatex(record,18,"\y Stop Recording")
	}else{
		formatex(record,18,"\y Start Recording")
	}
	if(g_isRecording[id] == 0 && g_FileHandler[id] != 0){
		formatex(stop,2,"\y")
		formatex(record,18,"\d Start Recording")
	}else{
		formatex(stop,2,"\d")
	}
	if(g_FileHandler[id] != 0){
		formatex(choose,2,"\d")
	}else{
		formatex(choose,2,"\y")
	}
	if(g_SaveSlot[id] == MAXSLOTS){
		formatex(record,18,"\d Start Recording")
	}
	if(g_SaveSlot[id] == MAXSLOTS){
		format(slot,1,"E")
	}else{
		format(slot,1,"%d",g_SaveSlot[id])
	}
	format(menu,255,"Active Slot: \r%s \d(%s)^n\r1%s Choose Slot^n\r2%s^n\r3%s Play/Pause^n\r4%s Stop^n\r5 \yRender Settings^n^n\r0. \wEXIT",slot,size,choose,record,playpause,stop)
	show_menu(id,RECORDKEYS,menu, -1, "Demo Recorder")
}
public choose_slot(id){
	new menu[256]
	format(menu,255,"\yChoose Slot");
	for( new i = 0 ; i < MAXSLOTS ; i++){
		static filename[128]
		get_filename(id,i,filename)
		if(file_exists(filename)){
			format(menu,255,"%s^n\r%d \w SLOT %d (%dKb)",menu,i+1,i,file_size(filename)/1024)
		}else{
			format(menu,255,"%s^n\r%d \w SLOT %d (FREE)",menu,i+1,i)
		}
	}
	format(menu,255,"%s^n\r9 Load from other player",menu)
	show_menu(id,SLOTKEYS,menu, -1, "Slot Chooser")
}
public foreign_loader(id){
	new menu[256]
	new szFileName[65],found,skip,currdir = open_dir(SAVEPATH,szFileName,64)
	new szSearch[36]
	formatex(szSearch,36,"_%s.rec",g_MapName)
	while(next_file(currdir,szFileName,64) && found < 8){
		if(skip < g_Offset[id]){
			skip++
			continue
		}
		if(containi(szFileName,szSearch) > 0){
			replace(szFileName,64,szSearch,"")
			found++
			format(menu,255,"%s^n\r%d \y%s",menu,found,szFileName)
			//log_amx(szFileName)
		}
	}
	if(g_Offset[id] >0){
		format(menu,255,"%s^n\r8 \y Previous",menu)
	}else{
		format(menu,255,"%s^n\r8 \d Previous",menu)
	}
	if(found<7){
		format(menu,255,"%s^n\r9 \d Next",menu)
		g_Next[id] = 0
	}else{
		g_Next[id] = 1
		format(menu,255,"%s^n\r9 \y Next",menu)
	}
	format(menu,255,"%s^n\r0 \ySlot Chooser",menu)
	close_dir(currdir)
	//log_amx(menu)
	show_menu(id,SLOTKEYS,menu, -1, "Foreign Loader")
}
public render_chooser(id){
	new menu[256],showto[4];
	if(g_GhostOwnerOnly[id]){
		copy(showto,3,"me")
	}else{
		copy(showto,3,"all")
	}
	formatex(menu,255,"\yRenderChooser^n\r1 \yRenderFX:^t^t\w %s^n\r2 \yRenderColor:^t\w %s^n\r3 \yRenderType:^t\w%s ^n\wRender Amount:^n\r4\y-  \w%d  \y+\r5^n\r6 \yShow to:\w%s^n^n\r0. \yBack",g_RenderFxName[g_RenderFx[id]],g_RenderColorName[g_RenderColor[id]],g_RenderName[g_RenderType[id]],g_RenderAmount[id],showto)
	show_menu(id,SLOTKEYS,menu,-1,"Render Chooser")
}
public loaderhandler(id,key){
	switch(key){
		case 7:{
			if(g_Offset[id] >= 7)
				g_Offset[id] -= 7
			else
				g_Offset[id] = 0
			foreign_loader(id)
		}
		case 8:{
			if(g_Next[id])
				g_Offset[id] += 7
			foreign_loader(id)
		}
		case 9:{
			choose_slot(id);
		}
		default:{
			g_SaveSlot[id] = MAXSLOTS;
			new szFileName[65],found,skip,currdir = open_dir(SAVEPATH,szFileName,64)
			new szSearch[36]
			formatex(szSearch,36,"_%s.rec",g_MapName)
			while(next_file(currdir,szFileName,64) && found < 8){
				if(skip < g_Offset[id]){
					skip++
					continue
				}
				if(containi(szFileName,szSearch) > 0){
					found++
				}
				if(found == (key+1)){
					format(g_ForeignFile[id],127,"%s%s",SAVEPATH,szFileName);
					log_amx("%s",g_ForeignFile[id])
					break;
				}
			}
			g_Offset[id] = 0;
			menu_show(id)
		}
	}
}
public renderhandler(id,key){
	switch(key){
		case 0:{
			if(g_RenderFx[id]+1 == sizeof g_RenderFxName)
				g_RenderFx[id] = 0
			else
				g_RenderFx[id]++
		}
		case 1:{
			if(g_RenderColor[id]+1 == sizeof g_RenderColorName)
				g_RenderColor[id] = 0
			else
				g_RenderColor[id]++
		}
		case 2:{
			if(g_RenderType[id]+1 == sizeof g_RenderName)
				g_RenderType[id] = 0
			else
				g_RenderType[id]++
		}
		case 3:{
			g_RenderAmount[id] -= 5
			if(g_RenderAmount[id] < 0){
				g_RenderAmount[id] = 255
			}
		}
		case 4:{
			g_RenderAmount[id] += 5
			if(g_RenderAmount[id] > 255){
				g_RenderAmount[id] = 0
			}
		}
		case 5:{
			if(g_GhostOwnerOnly[id])
				g_GhostOwnerOnly[id] = 0
			else
				g_GhostOwnerOnly[id] = 1
		}
		case 9:{
			menu_show(id);
			return PLUGIN_CONTINUE
		}
	}
	if(pev_valid(g_Ghost[id])){
		set_Ghost_Rendering(id)
	}
	render_chooser(id)
	return PLUGIN_HANDLED
}
public slothandler(id,key){
	if(key < MAXSLOTS){
		g_SaveSlot[id] = key
		menu_show(id)
	}else if(key == 8){
		foreign_loader(id)
	}
}
public menuhandler(id,key){
	switch (key) {
		case 9: {
			g_MenuOpen[id] = 0
			return PLUGIN_CONTINUE
		}
		case 0: {
			if(g_FileHandler[id] == 0){
				choose_slot(id);
			}else{
				menu_show(id)
			}
			return PLUGIN_CONTINUE;
		}
		case 1: { 
			if(g_isRecording[id] == 1 && g_SaveSlot[id] != MAXSLOTS){
				stop_record(id);
			}else if(g_FileHandler[id] == 0 && g_SaveSlot[id] != MAXSLOTS){
				start_record(id);
			}
			menu_show(id)
		}
		case 2: { 
			if(g_isRecording[id] == 0 && g_FileHandler[id] == 0 ){
				start_replay(id);
			}else if(g_isRecording[id] == 0){
				if(g_isPause[id]){
					g_isPause[id] = 0
					client_print(id,print_chat,"[%s] Playback resumed",PREFIX)
				}else{
					g_isPause[id] = 1
					client_print(id,print_chat,"[%s] Playback paused",PREFIX)
				}
			}
			menu_show(id)
		}
		case 3: { 
			if(g_isRecording[id] == 0 && g_FileHandler[id] != 0){
				client_print(id,print_chat,"[%s] Stopping playback",PREFIX)
				g_isPause[id] = 0;
				g_FileHandler[id] = 0;
			}
			menu_show(id)
		}
		case 4: {
			render_chooser(id)
		}
	}
	return PLUGIN_HANDLED
}
public fm_ghost_think(id){
	static szClassname[13]
	pev(id,pev_classname, szClassname,12)
	if( !equal(szClassname, "ghost_player") )
		return FMRES_IGNORED;
	static Float:ago,Float:origin[3],Float:angles[3],Float:veloc[3];
	static owner,data,sequence,gaitsequence
	owner = pev(id,pev_owner);
	//check weather paused
	if(g_isPause[owner] == 1 && is_user_connected(owner)){
		//let ghost wait
		set_pev(id,pev_nextthink,get_gametime()+0.5)
		//set velocity (not working for some reason)
		veloc[0] = 0.0
		veloc[1] = 0.0
		veloc[2] = 0.0
		set_pev(id,pev_velocity,veloc)
		return FMRES_IGNORED
	}
	g_Rec_Bytes[owner][1] += 48
	fread(g_FileHandler[owner],_:angles[0],BLOCK_INT)
	fread(g_FileHandler[owner],_:angles[1],BLOCK_INT)
	fread(g_FileHandler[owner],_:angles[2],BLOCK_INT)
	fread(g_FileHandler[owner],_:origin[0],BLOCK_INT)
	fread(g_FileHandler[owner],_:origin[1],BLOCK_INT)
	fread(g_FileHandler[owner],_:origin[2],BLOCK_INT)
	fread(g_FileHandler[owner],_:veloc[0],BLOCK_INT)
	fread(g_FileHandler[owner],_:veloc[1],BLOCK_INT)
	fread(g_FileHandler[owner],_:veloc[2],BLOCK_INT)
	fread(g_FileHandler[owner],sequence,BLOCK_INT)
	fread(g_FileHandler[owner],gaitsequence,BLOCK_INT)
	data = fread(g_FileHandler[owner],_:ago,BLOCK_INT)
	//log_amx("%f (%f %f %f)(%f %f %f)(%f %f %f)%d %d",ago,origin[0],origin[1],origin[2],angles[0],angles[1],angles[2],veloc[0],veloc[1],veloc[2],sequence,gaitsequence)
	if(data != 1){
		if(g_FileHandler[owner] != 0){
			fclose(g_FileHandler[owner])
			g_FileHandler[owner] = 0
		}
		if(g_MenuOpen[owner]){
			menu_show(owner)
		}
		fm_remove_entity(g_GhostWeapon[owner]);
		fm_remove_entity(g_Ghost[owner]);
		if(is_user_connected(owner)){
			client_print(owner,print_chat,"[%s] Playback Finished",PREFIX)
		}else{
			log_amx("removed ghost due to disconnect");
		}
		return FMRES_IGNORED;
	}
	set_pev(id,pev_nextthink,get_gametime()+ago)
	set_pev(id,pev_origin,origin)
	set_pev(id,pev_angles,angles)
	if(get_pcvar_num(g_CVar_igveloc) == 0){
		set_pev(id,pev_velocity,veloc)
	}
	//small bugfix
	if(gaitsequence == 3) gaitsequence = 4
	//dont know why but i have to switch them
	set_pev(id,pev_sequence,gaitsequence)
	set_pev(id,pev_gaitsequence,sequence)
	return FMRES_HANDLED;

}
public start_replay(id){
	log_amx("starting replay")
	if(g_FileHandler[id] != 0){
		client_print(id,print_chat,"[%s] Can't open File, maybe you are still recording",PREFIX)
		return PLUGIN_CONTINUE;
	}
	new fileName[128]
	get_filename(id,g_SaveSlot[id],fileName)
	g_Rec_Bytes[id][0] = filesize(fileName);
	//log_amx(fileName);
	g_FileHandler[id] = fopen(fileName,"rb");
	if(g_FileHandler[id] == 0){
		client_print(id,print_chat,"[%s] Couldn't open file mybe none existent",PREFIX)
	}else{
		client_print(id,print_chat,"[%s] Playback started",PREFIX)
		new version
		fread(g_FileHandler[id],version,BLOCK_INT)
		log_amx("Loading fileversion %d",version)
		switch(version){
			case 24 : {
				new weapon_model[33],model[33],mapname[33],rectime
				fread(g_FileHandler[id],rectime,BLOCK_INT)
				//read username
				for(new i = 0;i < 33;i++){
					fread(g_FileHandler[id],g_Rec_Playername[id][i],BLOCK_CHAR)
				}
				//read steamid
				for(new i = 0;i < 35;i++){
					fread(g_FileHandler[id],g_Rec_Steamid[id][i],BLOCK_CHAR);
				}
				//read mapname not used for now maybe later to do checks
				for(new i = 0;i < sizeof mapname;i++){
					fread(g_FileHandler[id],mapname[i],BLOCK_CHAR);
				}
				//read hostname
				for(new i = 0;i < 33;i++){
					fread(g_FileHandler[id],g_Rec_HostName[id][i],BLOCK_CHAR);
				}
				//read weapon
				for(new i = 0;i < sizeof weapon_model;i++){
					fread(g_FileHandler[id],weapon_model[i],BLOCK_CHAR);
				}
				//read model
				for(new i = 0;i < sizeof model;i++){
					fread(g_FileHandler[id],model[i],BLOCK_CHAR);
				}
				format_time(g_Rec_Time[id],20,"%c",rectime);
				//read the first wait... its useless =)
				fread(g_FileHandler[id],version,BLOCK_INT)
				//log_amx("%d %s %s %s %s %s %s %f",rectime,g_Rec_Playername[id],g_Rec_Steamid[id],mapname,g_Rec_HostName[id],weapon_model,model,version)
				g_Ghost[id] = fnCreateGhost(id,model);
				g_GhostWeapon[id] = fnGhostGiveItem(g_Ghost[id],weapon_model);
				set_Ghost_Rendering(id)
				g_Rec_Bytes[id][1] = 212
			}
			case 22 : {
				new weapon_model[33],model[33],mapname[33],rectime
				fread(g_FileHandler[id],rectime,BLOCK_INT)
				//read username
				for(new i = 0;i < 33;i++){
					fread(g_FileHandler[id],g_Rec_Playername[id][i],BLOCK_INT)
				}
				//read steamid
				for(new i = 0;i < 35;i++){
					fread(g_FileHandler[id],g_Rec_Steamid[id][i],BLOCK_INT);
				}
				//read mapname not used for now maybe later to do checks
				for(new i = 0;i < sizeof g_MapName;i++){
					fread(g_FileHandler[id],mapname[i],BLOCK_INT);
				}
				//read hostname
				for(new i = 0;i < sizeof g_HostName;i++){
					fread(g_FileHandler[id],g_Rec_HostName[id][i],BLOCK_INT);
				}
				//read weapon
				for(new i = 0;i < sizeof weapon_model;i++){
					fread(g_FileHandler[id],weapon_model[i],BLOCK_INT);
				}
				//read model
				for(new i = 0;i < sizeof model;i++){
					fread(g_FileHandler[id],model[i],BLOCK_INT);
				}
				format_time(g_Rec_Time[id],20,"%c",rectime);
				//read the first wait... its useless =)
				fread(g_FileHandler[id],version,BLOCK_INT)
				g_Ghost[id] = fnCreateGhost(id,model);
				g_GhostWeapon[id] = fnGhostGiveItem(g_Ghost[id],weapon_model);
				set_Ghost_Rendering(id)
				g_Rec_Bytes[id][1] = 812
			}
			default:{
				g_Ghost[id] = fnCreateGhost(id,"models/player/vip/vip.mdl");
				g_GhostWeapon[id] = fnGhostGiveItem(g_Ghost[id],"models/p_usp.mdl");
				set_Ghost_Rendering(id)
				g_Rec_Bytes[id][1] = 4
			}
		}		
	}
	return PLUGIN_HANDLED
}
public fm_plr_prethink(id){
	if(is_user_alive(id) && g_isRecording[id] != 0){
		static Float:ago,Float:origin[3],Float:angles[3],Float:veloc[3],Float:rate;
		static sequence,gaitsequence
		ago = get_gametime()-g_LastThink[id]
		if(ago < RECLIMITER) return FMRES_IGNORED
		rate = floatdiv(1.0,ago)
		rate = floatmul(rate,48.0)
		g_Rate[id] = floatround(rate);
		pev(id,pev_origin,origin)
		pev(id,pev_velocity,veloc)
		pev(id,pev_angles,angles)
		sequence = pev(id,pev_sequence)
		gaitsequence = pev(id,pev_gaitsequence)
		if((g_LastAngle[id][0] == angles[0] && g_LastAngle[id][1] == angles[1] && g_LastAngle[id][2] == angles[2] ) && (g_LastOrigin[id][0] == origin[0] && g_LastOrigin[id][1] == origin[1] && g_LastOrigin[id][2] == origin[2] ) && (g_LastVelocity[id][0] == veloc[0] &&	g_LastVelocity[id][1] == veloc[1] && g_LastVelocity[id][2] == veloc[2])) return FMRES_IGNORED
		g_LastAngle[id][0] = angles[0]
		g_LastAngle[id][1] = angles[1]
		g_LastAngle[id][2] = angles[2]
		g_LastOrigin[id][0] = origin[0]
		g_LastOrigin[id][1] = origin[1]
		g_LastOrigin[id][2] = origin[2]
		g_LastVelocity[id][0] = veloc[0]
		g_LastVelocity[id][1] = veloc[1]
		g_LastVelocity[id][2] = veloc[2]
		g_LastThink[id] = get_gametime()
		fwrite(g_FileHandler[id],_:ago,BLOCK_INT)
		fwrite(g_FileHandler[id],_:angles[0],BLOCK_INT)
		fwrite(g_FileHandler[id],_:angles[1],BLOCK_INT)
		fwrite(g_FileHandler[id],_:angles[2],BLOCK_INT)
		fwrite(g_FileHandler[id],_:origin[0],BLOCK_INT)
		fwrite(g_FileHandler[id],_:origin[1],BLOCK_INT)
		fwrite(g_FileHandler[id],_:origin[2],BLOCK_INT)
		fwrite(g_FileHandler[id],_:veloc[0],BLOCK_INT)
		fwrite(g_FileHandler[id],_:veloc[1],BLOCK_INT)
		fwrite(g_FileHandler[id],_:veloc[2],BLOCK_INT)
		fwrite(g_FileHandler[id],sequence,BLOCK_INT)
		fwrite(g_FileHandler[id],gaitsequence,BLOCK_INT)
		return FMRES_HANDLED
	}
	return FMRES_IGNORED
}
public start_record(id){
	new fileName[128]
	get_filename(id,g_SaveSlot[id],fileName)
	log_amx(fileName)
	g_FileHandler[id] = fopen(fileName,"wb")
	write_fileheader(id)
	g_isRecording[id] = 1
	client_print(id,print_chat,"[%s] Recording started",PREFIX)
}
public stop_record(id){
	g_isRecording[id] = 0
	fclose(g_FileHandler[id])
	g_FileHandler[id] = 0
	client_print(id,print_chat,"[%s] Recording stoped",PREFIX)
}
public get_filename(id,slot,fileName[]){
	if(slot < MAXSLOTS){
		format(fileName,127,"%s%s_%d_%s.rec",SAVEPATH,g_SteamId[id],slot,g_MapName)
	}else if(slot == MAXSLOTS){
		copy(fileName,127,g_ForeignFile[id]);
		//log_amx(fileName)		
	}
	
}
public write_fileheader(id){
	new name[33],weapon_model[33],model[33]
	//write fileversion
	fwrite(g_FileHandler[id],FILEVERSION,BLOCK_INT)
	//write time
	fwrite(g_FileHandler[id],get_systime(),BLOCK_INT)
	//write username
	get_user_name(id,name,32);
	for(new i = 0;i < sizeof name;i++){
		fwrite(g_FileHandler[id],name[i],BLOCK_CHAR)
	}
	//write steamid
	for(new i = 0;i < 35;i++){
		fwrite(g_FileHandler[id],g_SteamId[id][i],BLOCK_CHAR);
	}
	//write mapname
	for(new i = 0;i < sizeof g_MapName;i++){
		fwrite(g_FileHandler[id],g_MapName[i],BLOCK_CHAR);
	}
	//write hostname
	for(new i = 0;i < sizeof g_HostName;i++){
		fwrite(g_FileHandler[id],g_HostName[i],BLOCK_CHAR);
	}
	//write weapon
	pev(id,pev_weaponmodel2,weapon_model,32)
	//log_amx(weapon_model)
	for(new i = 0;i < sizeof weapon_model;i++){
		fwrite(g_FileHandler[id],weapon_model[i],BLOCK_CHAR);
	}
	//write model
	pev(id,pev_model,model,32)
	//log_amx(model)
	for(new i = 0;i < sizeof model;i++){
		fwrite(g_FileHandler[id],model[i],BLOCK_CHAR);
	}
}
public fnCreateGhost( iOwner ,szModel[]) {
	new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
		//make sure entity was created successfully
	if (pev_valid(ent)) {
		dllfunc(DLLFunc_Spawn,ent)
		engfunc(EngFunc_SetModel,ent,szModel)
		set_pev(ent, pev_classname, "ghost_player")
		set_pev(ent, pev_solid, SOLID_NOT)
		set_pev(ent,pev_movetype,MOVETYPE_PUSHSTEP)
		set_pev(ent, pev_owner, iOwner)
		set_pev(ent,pev_animtime, 2.0)
		set_pev(ent,pev_framerate, 1.0)
		set_pev(ent,pev_flags, FL_MONSTER)
		set_pev(ent,pev_controller_0, 125)
		set_pev(ent,pev_controller_1, 125)
		set_pev(ent,pev_controller_2, 125)
		set_pev(ent,pev_controller_3, 125)
		set_pev(ent, pev_nextthink, get_gametime() + 0.1)
		return ent;
	}else{
		client_print(iOwner,print_chat,"[%s] Ghost couldn't be created",PREFIX)
		fclose(g_FileHandler[iOwner])
		g_FileHandler[iOwner] = 0
	}
	return 0;
}
public fnGhostGiveItem( iEntity, szModel[] ) {
	new iWeapon = fm_create_entity( "info_target" );
	dllfunc(DLLFunc_Spawn,iWeapon)
	set_pev( iWeapon, pev_classname, "ghost_weapon" );
	set_pev( iWeapon, pev_movetype, MOVETYPE_FOLLOW );
	set_pev( iWeapon, pev_solid, SOLID_NOT );
	set_pev( iWeapon, pev_aiment, iEntity );
	engfunc(EngFunc_SetModel,iWeapon,szModel)
	return iWeapon;
	
}
public set_Ghost_Rendering(id){
	new fx,type
	switch(g_RenderFx[id]){
		case 0:
			fx = kRenderFxNone
		case 1:
			fx = kRenderFxHologram
		case 2:
			fx = kRenderFxGlowShell
	}
	switch(g_RenderType[id]){
		case 0:
			type = kRenderNormal
		case 1:
			type = kRenderTransAlpha
		case 2:
			type = kRenderTransAdd
	}
	fm_set_rendering(g_Ghost[id],fx,g_RenderColors[g_RenderColor[id]][0],g_RenderColors[g_RenderColor[id]][1],g_RenderColors[g_RenderColor[id]][2],type,g_RenderAmount[id]);
	fm_set_rendering(g_GhostWeapon[id],fx,g_RenderColors[g_RenderColor[id]][0],g_RenderColors[g_RenderColor[id]][1],g_RenderColors[g_RenderColor[id]][2],type,g_RenderAmount[id]);
}
public addToFullPack(es, e, ent, host, hostflags, player, pSet)
{
	static szClassname[13]
	if(is_user_connected(host) && pev_valid(ent) && pev(ent,pev_owner) < MAXPLAYERS){
		pev(ent,pev_classname, szClassname,12)
		if(g_Ghost[host] != ent && g_GhostOwnerOnly[pev(ent,pev_owner)] && equali("ghost_player",szClassname))
		{
			set_es(es, ES_Solid, SOLID_NOT)
			set_es(es, ES_RenderFx,kRenderFxNone)
			set_es(es, ES_RenderMode,kRenderTransAlpha)
			set_es(es, ES_RenderAmt, 0)
		}
	}
}
C++
Link of the plugin: https://forums.alliedmods.net/showthread.php?t=87314

Problem: playback doesnt work on 1.9.0 amxmodx

After succesfully recorded demo of player movement, when trying to play it, plugin after 0.1 sec finishing demo..so i guess problem line could be:

Line 430:
if(data != 1){
...
client_print(owner,print_chat,"[%s] Playback Finished",PREFIX)

meaning fread problem with 1.9.0?

I hope someone can help, thanks! :)
 
Сообщения
1,353
Реакции
529
Помог
92 раз(а)
jocasrb, did you try to run the plugin compiled under 1.8.2? Maybe it will work?
 
Сообщения
167
Реакции
32
present Good idea...tryed now and eveyething is the same (plugin finishes the playback at the same moment when its started)
 
Сообщения
167
Реакции
32
I will pay the coder who fix this 'line' for 200 rubles..also i can help with more things if needed...for example, now its logging only one line from the plugin (that is the problem)

C:
log_amx("%f (%f %f %f)(%f %f %f)(%f %f %f)%d %d",ago,origin[0],origin[1],origin[2],angles[0],angles[1],angles[2],veloc[0],veloc[1],veloc[2],sequence,gaitsequence)

->

[record.amxx] 0.030004 (-378.743804 120.491287 494.031250)(-10.030517 -104.046020 0.000000)(0.000000 0.000000 0.000000)75 1
so its like its only first frame loaded of the demo, and its gone...probably should be >100 lines
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу