铁血丹心

 找回密码
 我要成为铁血侠客
搜索
查看: 1749|回复: 3

压缩存档的一个方案

[复制链接]
发表于 2017-9-8 10:55 | 显示全部楼层 |阅读模式
lua版的存档未经压缩,尺寸比较大,文件分为多个,分享很不方便。

因为lua版中的存档代码很多地方是分开写的,如果直接在内存中压缩,程序要改的地方可能比较多。

那么我们可以增加两个压缩和解压缩的函数,在存档时先按照以前的方案写,然后压缩文件,再将未压缩的文件删除,读档时也类似。这样可以少改一些代码。

首先下载附件,里面是头文件和库文件,需要在visual studio里面配置好,这个就不细讲了。
要改的代码如下:

luafun.c增加这两个函数(请自己在jymain.h里添加声明,以及所需的头文件)。

  1. int Byte_unzip(lua_State *pL)
  2. {
  3.     const char *filenamezip = lua_tostring(pL, 1);
  4.     int n = lua_gettop(pL);
  5.     int i;
  6.     unzFile zip;
  7.     zip = unzOpen(filenamezip);
  8.     for (i = 2; i <= n; i++)
  9.     {
  10.         const char *filename = lua_tostring(pL, i);
  11.         unz_file_info zi = { 0 };
  12.         if (unzLocateFile(zip, filename, NULL) != UNZ_OK)
  13.         {
  14.             break;
  15.         }
  16.         char s[100];
  17.         unzGetCurrentFileInfo(zip, &zi, s, 100, NULL, 0, NULL, 0);
  18.         unzOpenCurrentFile(zip);

  19.         FILE *fp;
  20.         if ((fp = fopen(filename, "wb")) == NULL)
  21.         {
  22.             break;
  23.         }
  24.         void* buf = malloc(8192);
  25.         int c = 0;
  26.         while (c < zi.uncompressed_size)
  27.         {
  28.             int len = zi.uncompressed_size - c;
  29.             if (len > 8192) len = 8192;
  30.             unzReadCurrentFile(zip, buf, 8192);
  31.             fwrite(buf, len, 1, fp);
  32.             c += 8192;
  33.         }
  34.         fclose(fp);
  35.         free(buf);
  36.     }
  37.     unzClose(zip);
  38.     return 0;
  39. }


  40. int Byte_zip(lua_State *pL)
  41. {
  42.     zip_fileinfo zi = { 0 };
  43.     const char *filenamezip = lua_tostring(pL, 1);
  44.     int n = lua_gettop(pL);
  45.     int i;   
  46.     zipFile zip = zipOpen(filenamezip, APPEND_STATUS_CREATE);
  47.     for (i = 2; i <= n; i++)
  48.     {
  49.         const char *filename = lua_tostring(pL, i);
  50.         FILE *fp;
  51.         if ((fp = fopen(filename, "rb")) == NULL)
  52.         {
  53.             break;
  54.         }
  55.         fseek(fp, 0, SEEK_END);
  56.         int length = ftell(fp);
  57.         fseek(fp, 0, 0);
  58.         char* s = malloc(length + 1);
  59.         fread(s, length, 1, fp);
  60.         fclose(fp);
  61.         get_file_date(filenamezip, &zi.dos_date);
  62.         //zi.dos_date = time(NULL);
  63.         zipOpenNewFileInZip(zip, filename, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
  64.         zipWriteInFileInZip(zip, s, length);
  65.         zipCloseFileInZip(zip);
  66.         free(s);
  67.     }
  68.     zipClose(zip, NULL);
  69.     return 0;
  70. }

  71. int Byte_loadfilefromzip(lua_State *pL)
  72. {
  73.     char *p = (char *)lua_touserdata(pL, 1);
  74.     const char *filenamezip = lua_tostring(pL, 2);
  75.     const char *filename = lua_tostring(pL, 3);
  76.     int start = (int)lua_tonumber(pL, 4);
  77.     int length = (int)lua_tonumber(pL, 5);

  78.     unzFile zip;
  79.     unz_file_info zi = { 0 };
  80.     zip = unzOpen(filenamezip);
  81.     if (unzLocateFile(zip, filename, NULL) != UNZ_OK)
  82.     {
  83.         return 0;
  84.     }
  85.     char s[100];
  86.     unzGetCurrentFileInfo(zip, &zi, s, 100, NULL, 0, NULL, 0);
  87.     unzOpenCurrentFile(zip);

  88.     const int size_buf = 8192;
  89.     void* buf = malloc(size_buf);
  90.     void* buf2 = malloc(zi.uncompressed_size);
  91.     int c = 0;
  92.     while (c < zi.uncompressed_size)
  93.     {
  94.         int len = zi.uncompressed_size - c;
  95.         if (len > size_buf) len = size_buf;
  96.         unzReadCurrentFile(zip, buf, size_buf);
  97.         memcpy((char*)buf2+c,buf,len);
  98.         c += size_buf;
  99.     }
  100.     unzClose(zip);
  101.     memcpy(p, (char*)buf2+start,length);
  102.     free(buf);
  103.     free(buf2);
  104.     return 0;
  105. }

复制代码


jymain.c里面初始化lua函数名的地方当然也要改一下:
  1. static const struct luaL_Reg bytelib [] = {
  2.       {"create", Byte_create},
  3.       {"loadfile", Byte_loadfile},
  4.       {"savefile", Byte_savefile},
  5.       {"unzip", Byte_unzip},
  6.       {"zip", Byte_zip},
  7.       {"get16", Byte_get16},
  8.       {"set16", Byte_set16},
  9.       {"getu16", Byte_getu16},
  10.       {"setu16", Byte_setu16},
  11.       {"get32", Byte_get32},
  12.       {"set32", Byte_set32},
  13.       {"getstr", Byte_getstr},
  14.       {"setstr", Byte_setstr},
  15.           {NULL, NULL}
  16. };
复制代码


这样就添加了两个专用于压缩或者解压的函数Byte.zip和Byte.unzip。它们的参数个数都是2个到无限多个。用法如下:
  1. Byte.unzip('data/save/1.zip', 'r.grp','d.grp','s.grp')
  2. Byte.zip('data/save/1.zip', 'r.grp','d.grp','s.grp')
复制代码

某些情况下如果只需要解压r.grp,也可以写:
  1. Byte.unzip('data/save/1.zip', 'r.grp')
复制代码

在任务完成后可以用os.remove删除文件。
但是需要注意,压缩的时候是新建一个压缩包,故一定要一次将所有文件都写完。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2017-9-8 11:00 | 显示全部楼层
可以很6
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2017-9-8 11:00 | 显示全部楼层
非常有必要的功能
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2017-10-26 13:56 | 显示全部楼层
顶顶顶顶顶
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。

本版积分规则

小黑屋|手机版|铁血丹心

GMT+8, 2024-11-21 20:27

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表