打包游戏

跳转至: 导航, 搜索

打包游戏 页面包含如何使用 openSUSE 构建服务 为 openSUSE 和其他发行版打包游戏的指南。

除了标准打包指南,这里也有一些强烈推荐在打包游戏时遵守的规则。

软件包拆分

  • 如果可能,软件包文件和数据文件应该分开打包,以降低 bugfix 发布时的包尺寸。如果上游提供了分开的游戏数据源代码压缩包,那这就是必须的。
  • 在大多数情况下,游戏数据包 (关卡,美工,声音和音乐) 应该 BuildArch: noarch
  • 数据文件 (地图,图片,声音) 放到  %{_datadir}/%{name} ,而不是 %{_datadir}/games/%{name} 。可执行文件放到  %{_bindir} 而不是 /usr/games。根据 FHS 标准,/usr/share/games/usr/games 的使用是可选的,我们推荐不使用以保持一致性,这样游戏就和其他应用程序一样了。
  • 如果您已知游戏版本 1.3.3 和 1.2 及以后的数据包能够兼容,您可以使用如下方案:

game.spec

Version:  1.3.3
Requires: game-data >= 1.2

game-data.spec

Version: 1.2
Requires: game >= 1.2

常用函数库

  • 对于需要 SDL 的游戏来说在 BuildRequires 中使用 SDL-devel (也可能需要其他的如 like SDL_image-devel, SDL_mixer-devel, SDL_net-devel, 等等。) 。我们的 SDL 函数库提供了这些符号。但直接使用 libSDL-devel 在 Fedora, Mandriva 和老版本 openSUSE 发行版上不能工作。

文件和权限

  • 高分和运行时配置文件根据 FHS 应该放在 /var/games/%{name} 。如果软件包只在该位置放了一个文件,那可以放弃 %{name} 子目录,直接把文件放到 /var/games。
  • 游戏的手册页面根据 FHS 应该放在部分 6: %{_mandir}/man6/
  • spec 文件的 RPM 组是: Group: Amusements/Games
  • 桌面文件分类: Categories=Game; 此列表中任何合适的。关于如何正确使用这些分类请参考 此邮件
  • 必须 包含许可协议文件以声明法律状态,即使上游没有在源代码压缩包中提供它。
  • 游戏服务守护精灵,诸如 xpilot-ng-server 和 wesnoth 提供的这些,必须以它们自身的用户 ID 运行,不能是 'root', 'games', 或者其他系统用户。
  • 所有 %files 必须由 root所有。也有一些特定的共享文件是例外,比如积分榜。
  • 如果需要,游戏应该预设组 ID 'games' 以允许共享积分榜文件。但只有在需要的时候才能这么做,一旦不需要了,记得移除 setgid 权限。下面实例显示了如何妥善的移除 setuid/setgid 权限。而且 setgid 代码需要先经 SuSE 安全团队同意。
/* 保留一个到积分榜文件的全局指针。我知道全局变量很脏,应该避免。
* 您的应用程序可以换方法做。这就是个例子。
*/
extern FILE *scoreboard_filehandle;

/*
* 注意我们要在打开积分榜文件后,任何其他操作前,在 main() 中立刻移除 setgid。
* 这最小化了运行 setuid/setgid 的代码量
*/
int main(int argc, char **argv) {
gid_t realgid;
uid_t realuid;

/* 打开积分榜文件。这可能为 NULL!使用此变量的用户必须在使用前检测,
* 如果积分榜为 NULL 那就不要再试着去写入了。
*
* 该文件使用 "r+" 权限打开以保护已有内容。
* 这允许程序首先阅读积分榜,然后使用新值写入。
* 请确保您在读取后没有 close() 文件,否则您将不能再次写入。
*/
scoreboard_filehandle=fopen(SCOREBOARDFILE, "r+");

/* 确定当前 ID
*/
realgid = getgid();
realuid = getuid();

/* 这是我们移除 setuid/setgid 权限的地方。
*/
if (setresgid(-1, realgid, realgid) != 0) {
perror("Could not drop setgid privileges.  Aborting.");
exit(1);
}
if (setresuid(-1, realuid, realuid) != 0) {
perror("Could not drop setuid privileges.  Aborting.");
exit(1);
}
/* ...继续设置游戏... */

不是为 Linux/Unix 设计的游戏

有些游戏不是为 Linux/Unix 设计的:它们在一个独立目录下运行,并试图写入它。好的解决办法是创建一个 bash 封装,该封装:

  1. 在用户的 home 下创建一个目录
  2. 系统链接 /usr/share/%{name} 中的游戏目录到它当中
  3. cd 到用户目录并运行真正的可执行文件

脚本应该像这样:

#!/bin/sh
GAME_LOCAL_DIR=$HOME/.mygame
GAME_DATA_DIR=/usr/share/mygame
GAME_EXECUTABLE=/usr/libexec/mygame/mygame
mkdir -p $GAME_LOCAL_DIR
cd $GAME_LOCAL_DIR
for dir in techs data maps tilesets; do
ln -snf $GAME_DATA_DIR/$dir $dir
done
test -d savegames || mkdir savegames
test -e mygame.ini || cp $GAME_DATA_DIR/mygame.ini mygame.ini
exec $GAME_EXECUTABLE "$@"

OpenGL 封装

如果游戏需要 3D 加速图形显卡您需要使用 DRI 检测封装,该封装在没有 DRI 可用时显示错误对话框,抱怨自由软件和 3D 驱动,然后退出。 您必须要做的是:

  1. 添加: Requires: opengl-games-utils
  2. 添加到: %install:
     ln -s opengl-game-wrapper.sh $RPM_BUILD_ROOT%{_bindir}/%{name}-wrapper
  3. 添加 %{_bindir}/%{name}-wrapper%files
  4. 修改 .desktop 文件的 Exec 字段,从 %{name} 改为 %{name}-wrapper

这假设您的主执行程序名为 %{name},否则请相应修改。

如果您已经由于其它原因有了一个封装脚本,您可以直接合并 checkDriOk 函数到您的封装,而不需要再做一个封装的封装,实例见 vegastrike 的 vegastrike-wrapper.sh 文件。