Cocos2d-x 记录游戏日志并上传

Cocos2d-x 记录游戏日志并上传,第1张

概述在游戏测试过程中我们可能会遇到有些偶发性的Bug不能复现,不能定位的问题,这就很尴尬了。 所以我们在这里实现一下实时记录游戏日志的功能。 记录日志,具体记些什么呢?不可能把每一步都记的很清楚,但是我们在开发过程中,每一步可能会打印一些特定的输出,我们就在输出上做一些手脚,把它的每一行都记录下来。 环境:Cocos2d-x quick if DEBUG_MODE then --把打印的log写入文 在游戏测试过程中我们可能会遇到有些偶发性的BUG不能复现,不能定位的问题,这就很尴尬了。
所以我们在这里实现一下实时记录游戏日志的功能。


记录日志,具体记些什么呢?不可能把每一步都记的很清楚,但是我们在开发过程中,每一步可能会打印一些特定的输出,我们就在输出上做一些手脚,把它的每一行都记录下来。


环境:Cocos2d-x quick


if DEBUG_MODE then	--把打印的log写入文件	LOG_file_name = "log_file.txt"	BACKUP_LOG_file_name = "backup_log_file.txt"	--如果之前写过文件就把之前的替换成备份	if io.exists(device.writablePath..LOG_file_name) then		--检查之前是否有备份		if io.exists(device.writablePath..BACKUP_LOG_file_name) then			--如果有备份则删掉备份			os.execute("rm "..device.writablePath..BACKUP_LOG_file_name)		end		--把之前的文件替换成备份文件		io.open(device.writablePath..BACKUP_LOG_file_name,'a+')		os.execute("mv " .. device.writablePath..LOG_file_name .. " " .. device.writablePath..BACKUP_LOG_file_name)	end	--新建一个新的空文件	print(os.execute("touch "..device.writablePath..LOG_file_name))	LOG_file_PATH = io.open(device.writablePath..LOG_file_name,'a+')	--重写print 让打印的东西能同时写入到文件里	old_print = print	print = function (...)		old_print(...)		--写入		if ... then			local args = {...}			local s = args[1]			if #args > 1 then				for i=2,#args do					s = s .. "    |    " .. args[i]				end			end			LOG_file_PATH:write(tostring(s).."\n")			LOG_file_PATH:flush()		end	endend



记录Log的方法就到此为止了,DEBUG_MODE在开启的时候没写一行print都会向文件里写入一行。


下面说一下上传

上传我们用了libcurl,因为在iOS和AndroID的系统中没有集成,所以不能直接调用os.execute(curl xxxxx),改在C++层进行上传的 *** 作。

新建Logfile.cpp和Logfile.h两个文件

Logfile.cpp

////  Logfile.cpp//  vegasnights////  Created by Donliu on 16/7/6.////#include "Logfile.h"/* parse headers for Content-Length */ size_t Logfile::getcontentlengthfunc(voID *ptr,size_t size,size_t nmemb,voID *stream){    int r;    long len = 0;    /* _snscanf() is Win32 specific */    //r = _snscanf(ptr,size * nmemb,"Content-Length: %ld\n",&len);    r = sscanf((const char*)ptr,&len);    if (r) /* Microsoft: we don't read the specs */        *((long *) stream) = len;    return size * nmemb;}/* discard downloaded data */size_t Logfile::discardfunc(voID *ptr,voID *stream){    return size * nmemb;}//write data to uploadsize_t Logfile::writefunc(voID *ptr,voID *stream){    return fwrite(ptr,size,nmemb,(file*)stream);}/* read data to upload */size_t Logfile::readfunc(voID *ptr,voID *stream){    file *f = (file*)stream;    size_t n;    if (ferror(f))        return CURL_READFUNC_ABORT;    n = fread(ptr,f) * size;    return n;}int Logfile::upload(CURL *curlhandle,const char * remotepath,const char * localpath,const char * userpwd,long timeout,long trIEs){    file *f;    long uploaded_len = 0;    CURLcode r = CURLE_GOT_nothing;    int c;    f = fopen(localpath,"rb");    if (f == NulL) {        perror(NulL);        return 0;    }    curl_easy_setopt(curlhandle,CURLOPT_UPLOAD,1L);    curl_easy_setopt(curlhandle,CURLOPT_URL,remotepath);    curl_easy_setopt(curlhandle,CURLOPT_USERPWD,userpwd);    curl_easy_setopt(curlhandle,CURLOPT_CONNECTTIMEOUT,1);    if (timeout)        curl_easy_setopt(curlhandle,CURLOPT_FTP_RESPONSE_TIMEOUT,timeout);    curl_easy_setopt(curlhandle,CURLOPT_headerFUNCTION,getcontentlengthfunc);    curl_easy_setopt(curlhandle,CURLOPT_headerDATA,&uploaded_len);    curl_easy_setopt(curlhandle,CURLOPT_WRITEFUNCTION,discardfunc);    curl_easy_setopt(curlhandle,CURLOPT_READFUNCTION,readfunc);    curl_easy_setopt(curlhandle,CURLOPT_READDATA,f);    curl_easy_setopt(curlhandle,CURLOPT_FTPPORT,"-"); /* disable passive mode */    curl_easy_setopt(curlhandle,CURLOPT_FTP_CREATE_MISSING_Dirs,CURLOPT_VERBOSE,1L);    for (c = 0; (r != CURLE_OK) && (c < trIEs); c++) {        /* are we resuming? */        if (c) { /* yes */            /* determine the length of the file already written */            /*             * With NOBODY and NOheader,libcurl will issue a SIZE             * command,but the only way to retrIEve the result is             * to parse the returned Content-Length header. Thus,* getcontentlengthfunc(). We need discardfunc() above             * because header will dump the headers to stdout             * without it.             */            curl_easy_setopt(curlhandle,CURLOPT_NOBODY,1L);            curl_easy_setopt(curlhandle,CURLOPT_header,1L);            r = curl_easy_perform(curlhandle);            if (r != CURLE_OK)                continue;            curl_easy_setopt(curlhandle,0L);            curl_easy_setopt(curlhandle,0L);            fseek(f,uploaded_len,SEEK_SET);            curl_easy_setopt(curlhandle,CURLOPT_APPEND,1L);        }        else { /* no */            curl_easy_setopt(curlhandle,0L);        }        r = curl_easy_perform(curlhandle);    }    fclose(f);    if (r == CURLE_OK)        return 1;    else {        fprintf(stderr,"%s\n",curl_easy_strerror(r));        return 0;    }}// 下载int Logfile::download(CURL *curlhandle,long trIEs){    file *f;    curl_off_t local_file_len = -1 ;    long filesize =0 ;    CURLcode r = CURLE_GOT_nothing;    struct stat file_info;    int use_resume = 0;    //获取本地文件大小信息    if(stat(localpath,&file_info) == 0)    {        local_file_len = file_info.st_size;        use_resume = 1;    }    //追加方式打开文件,实现断点续传    f = fopen(localpath,"ab+");    if (f == NulL) {        perror(NulL);        return 0;    }    curl_easy_setopt(curlhandle,userpwd);    //连接超时设置    curl_easy_setopt(curlhandle,timeout);    //设置头处理函数    curl_easy_setopt(curlhandle,&filesize);    // 设置断点续传    curl_easy_setopt(curlhandle,CURLOPT_RESUME_FROM_LARGE,use_resume?local_file_len:0);    curl_easy_setopt(curlhandle,writefunc);    curl_easy_setopt(curlhandle,CURLOPT_WRITEDATA,CURLOPT_nopROGRESS,1L);    r = curl_easy_perform(curlhandle);    fclose(f);    if (r == CURLE_OK)        return 1;    else {        fprintf(stderr,curl_easy_strerror(r));        return 0;    }}voID Logfile::lua_upload(const char * remotepath,const char *localpath,const char * userpwd){    CURL *curlhandle = curl_easy_init();    upload(curlhandle,remotepath,localpath,userpwd,1,3);    curl_easy_cleanup(curlhandle);    curl_global_cleanup();}

Logfile.h:
////  Logfile.hpp//  vegasnights////  Created by Donliu on 16/7/6.////#ifndef Logfile_hpp#define Logfile_hpp#include <stdlib.h>#include <stdio.h>#include <curl/curl.h>#include <sys/stat.h>class Logfile {public:    static size_t getcontentlengthfunc(voID *ptr,voID *stream);    static size_t discardfunc(voID *ptr,voID *stream);    static size_t writefunc(voID *ptr,voID *stream);    static size_t readfunc(voID *ptr,voID *stream);    static int upload(CURL *curlhandle,long trIEs);    static int download(CURL *curlhandle,long trIEs);    static voID lua_upload(const char * remotepath,const char * userpwd);};#endif /* Logfile_hpp */
很清爽的一段代码。我把lua_upload这个方法抛到Lua里了,直接调用就好。 总结

以上是内存溢出为你收集整理的Cocos2d-x 记录游戏日志并上传全部内容,希望文章能够帮你解决Cocos2d-x 记录游戏日志并上传所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1082332.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-27
下一篇2022-05-27

发表评论

登录后才能评论

评论列表(0条)

    保存