惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
S
Security @ Cisco Blogs
S
Secure Thoughts
Attack and Defense Labs
Attack and Defense Labs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
Recent Commits to openclaw:main
Recent Commits to openclaw:main
H
Hacker News: Front Page
博客园 - 叶小钗
H
Heimdal Security Blog
Microsoft Security Blog
Microsoft Security Blog
Forbes - Security
Forbes - Security
AI
AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Troy Hunt's Blog
罗磊的独立博客
Application and Cybersecurity Blog
Application and Cybersecurity Blog
爱范儿
爱范儿
GbyAI
GbyAI
The Last Watchdog
The Last Watchdog
TaoSecurity Blog
TaoSecurity Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
D
DataBreaches.Net
Recent Announcements
Recent Announcements
Schneier on Security
Schneier on Security
C
Cisco Blogs
美团技术团队
D
Docker
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
月光博客
月光博客
雷峰网
雷峰网
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
H
Hackread – Cybersecurity News, Data Breaches, AI and More
A
Arctic Wolf
B
Blog RSS Feed
Cisco Talos Blog
Cisco Talos Blog
C
Cybersecurity and Infrastructure Security Agency CISA
V
Vulnerabilities – Threatpost
V2EX - 技术
V2EX - 技术
Y
Y Combinator Blog
N
News and Events Feed by Topic
www.infosecurity-magazine.com
www.infosecurity-magazine.com
W
WeLiveSecurity
Security Archives - TechRepublic
Security Archives - TechRepublic
G
GRAHAM CLULEY
Jina AI
Jina AI
Hugging Face - Blog
Hugging Face - Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
The Hacker News
The Hacker News

风萧古道 - 勤学苦练,年复一年

游戏服务器开发经验(五)应对复杂需求 沉浸式体验东汉末年生活 - 《真三国无双 起源》玩后感 怒其不争!致2025年HLTV的Top18-NiKo Linux家用服务器维护指南 游戏服务器开发经验(四)避免写Bug的习惯、技巧和心态 游戏服务器开发经验(三)线上维护 游戏服务器开发经验(二)避免内存泄露 35岁找不到工作,绝对不会是软件开发人员的结局 用爱发电项目开发两个月的心得体会 以魏延“子午谷奇谋”讨论软件需求可行性问题 MQTT协议中可变长度的具体计算方式(有计算过程解析) 关于游戏服务器配置表功能的探讨 Java并发编程中上锁的几种方式 如何用C++分割一个字符串? CSAPP第二章-信息的表示与处理 我的自我介绍 Windows XP虚拟机中文版无需激活下载 Java TreeSet的一些用法和特性 Linux C++ Socket实战 传统软件服务器与游戏服务器架构区别 独立个人项目开发心得 - 任务切分、挑战性、实用性和半途而废 使用Python实现简单UDP Ping 使用Python开发一个简单的web服务器 Kotlin手动实现一个最简单的哈希表 Kotlin实现二叉堆、大顶堆、优先级队列 搭建Spark实战环境(3台linux虚拟机集群)(一)样板机的搭建 Springboot操作MongoDB,包括增改查及复杂操作 Unison在Linux下的安装与使用 Java实现类似WINSCP访问远程Linux服务器,执行命令、上传文件、下载文件 一个被废弃的项目——自动爬取信息然后发给我自己邮箱上 Python连接MongoDB和Oracle实战 MongoDB常用查询语句 vue和springboot项目部署到Linux服务器 Python的一些用法(可能不定时更新) java正则表达式 - 双反斜杠(\)和Pattern的matches()与find() 简述爬虫对两种网站的不同爬取方式 Vue的路由配置及手动改地址栏为啥又跳转回来?? [JavaScript]JS基础知识 [Mybatis]逆向工程中Select语句查询不出‘TEXT’字段 [编译原理]FIRST、FOLLOW和SELECT [Spring]Spring学习笔记 [算法]分布估计算法 - 一种求解多维背包问题的混合分布估计算法_王凌 [日常]我做独立博客的原因 人间值得 深入理解计算机系统 想想就开心! 最重要的事,只有一件 藏书 被讨厌的勇气 关于 简历 朋友 尊重自己:给予与接收的心灵艺术
游戏服务器开发经验(一)道具防刷
JonathanLin · 2025-02-16 · via 风萧古道 - 勤学苦练,年复一年

前言

在多年的游戏服务器开发工作中,在大多数时候,开发内容仅仅是将策划的需求“翻译”成服务器程序代码。但是这份工作需要的严谨程度非常高,远远不止将需求实现而已。 有一些内容是开发过程中就需要有意识去注意的。如:必须校验客户端传参;先扣除道具,再改状态,最后发奖励以保证防止玩家刷奖励等。做到这一步,基本上能保证客户端的行为能在服务器的控制以内。

但还有一些内容,是由于项目长期开发过程中,多个需求互相杂糅导致的问题。比如今天的功能可能和去年年初的功能耦合,但是触发条件比较苛刻,埋得比较深。这种问题一般不会是什么影响服务器启动的大问题,但是很有可能会造成业务逻辑的漏洞。面对这种问题,我们是比较难在开发中能提前预知,一般是靠人力测试或者接口压力测试的时候查看报错日志来发现。

还有一些是需求过于复杂,变动太大,程序跟不上策划思路。这种情况其实更考验沟通能力,准确来说,是发现策划“核心需求”的能力。策划想要的东西可能和他说的内容并不一致,他想要的需求也和他真正告诉你的不一致。所以这就要求我们的代码能够支持一定的灵活性,能够提前预判策划真正想要的目标效果。当然这也需要我们程序员多玩不同类型的游戏,从而尽可能让思路和策划在同一水平面上。

本系列是本人在多年游戏服务器开发过程中,积累了些许经验,闲暇时总结在此处。

道具防刷

网络游戏最担心的事情,除了服务器崩溃之外,就是道具被玩家无限重复获得,俗称“刷奖励”。在大多数情况下,发放道具都是非常基础的功能。一般发放道具这一步不会有什么太大问题,问题主要会出现在发放道具前的业务逻辑校验。

如果校验的条件覆盖面不足,当玩家没有付出足够代价的情况下,获得了道具,会大大影响服务器内的经济系统。好比有人发现能去商店“零元购”而不被制裁,那就没有人愿意劳动了。

防刷原则:校验条件 -> 扣消耗 -> 改状态 -> 发奖励

无论什么情况,都务必遵循此条件:校验条件 -> 扣消耗 -> 改状态 -> 发奖励。

一般来说,校验条件放最前面没有异议,但是扣消耗、改状态、发奖励却不一定大家都会认同。在有事务和锁的情况下,完全可以做到开启事务后,对核心对象上锁,校验好消耗和奖励,然后一并提交。但是对于游戏服务器来说,消耗和奖励是允许一定程度的误差的(因为可以后期补发、扣除等操作)并且服务器性能的优先级高于消耗和奖励的优先级。如果每次玩家去游戏商城进行道具购买,或者挑战关卡通关都要有事务和锁的开销,会大大影响效率。

因此在没有事务和锁的情况下,扣消耗、改状态、发奖励这三个步骤中,我们优先要让玩家吃亏,必须先扣除消耗。然后再修改状态,让下一次请求来临时校验新的条件。最后再发放奖励。

补救措施:完善的资源道具产销日志

玩家在游戏中的每一笔消耗和获得,都需要记录下来。除了玩家信息、道具信息、变更数量等一定要记录的内容之外,还至少包含以下内容:日志枚举(数字,用于数据库中创建索引),产销细节(提供一个字符串,记录本次产销相关的事件,关联的id,如通关的副本id、购买的商品id等)。如此一来,即使真的存在被刷道具的情况,也能快速定位到被刷的数量。

这个日志最好能不要删除。这里就可以考虑使用大数据相关的数据库来存储这种大量结构化数据了。

事前预防:最重要的是把状态改对

被刷道具的原因基本上都是状态没有正确更改。大部分情况下,用心的开发人员会记得修改状态。

但是还会有一种比较隐秘的Bug情况:修改的状态可能并不是这个业务需要的状态。这种情况最容易发生在复制其他功能的代码到自己的功能,然后删改细节的时候不小心遗漏。

事前预防:填写正确的产销日志信息

另外,道具产销的日志也一定要认真检查填写的日志信息。这一部分是非常容易忽略的。因为即使代码进行了自测,道具正常扣除与增加,也无法直观地看到日志里的内容。

事前预防:任何一行代码,有条件都要自测

没有人比你懂你的代码,哪怕是用心Review你代码的领导。所以千万不要有侥幸心理,有条件自测就多点一下,能断点走一遍看看就走一遍。这个过程并不会花费太多时间。但是却能很快让你看到代码中的缺漏。