Cocos Creator 一種「無(wú)侵入」資源加密方案

一、前言

Cocos Creator 打包后的素材資源寄啼,如:圖片逮光,聲音等。默認(rèn)是保持原始格式墩划,只要遇到破解黨涕刚,那么他們極有可能很簡(jiǎn)單就直接獲取到這部分素材資源。

針對(duì)這個(gè)問(wèn)題乙帮,大部分同學(xué)都會(huì)有一種資源加密的需求杜漠,即對(duì)打包后的資源進(jìn)行加密,讓破解黨 不那么容易 獲取到資源。

由此驾茴,引出了很多關(guān)于資源加密一些訴求盼樟,包括但不限于:

但是,你可能發(fā)現(xiàn)锈至,通篇下來(lái)晨缴,可能并沒(méi)有一個(gè)完整的流程方案。

  • 或是過(guò)于注重怎么加解密
  • 或是僅支持圖片資源裹赴,其他資源沒(méi)涉及
  • 或是僅涉及到部分平臺(tái)喜庞,比如:只關(guān)注了原生平臺(tái)
  • 或是需要侵入到項(xiàng)目代碼,需要使用指定的資源加載器

(鑒于目前的搜索結(jié)果)總結(jié)下來(lái)棋返,開(kāi)源出來(lái)的好像還沒(méi)有一整套Cocos Creator資源加解密流程方案的樣子延都。

二、Cocos Creator Build Encrypt 方案介紹

這次為大家?guī)?lái)一種 Cocos Creator 「無(wú)侵入」 「全資源支持」 「跨平臺(tái)」 「資源處理流」 方案睛竣。

以下為我關(guān)于上述四個(gè)加粗特性的定義:

  • 「無(wú)侵入」:使用此方案晰房,開(kāi)發(fā)者只需要針對(duì) Cocos Creator 構(gòu)建后的輸出目錄 進(jìn)行執(zhí)行指定命令,即完成資源加密射沟。 實(shí)際游戲項(xiàng)目不需要加入/刪除/修改代碼等其他操作殊者,全程無(wú)侵入
  • 「全資源支持」:此方案可以對(duì) Cocos Creator 引擎本身所支持的 所有資源文件(如:.txt验夯,.json, .png, .mp3, .fnt等等)進(jìn)行加密 猖吴,并且依舊「無(wú)侵入」。
  • 「跨平臺(tái)」:此方案可以針對(duì)不同版本的 Cocos Creator 進(jìn)行單獨(dú)適配挥转,并且可以對(duì)每個(gè) Cocos Creator 支持發(fā)布的所有平臺(tái)進(jìn)行單獨(dú)適配海蔽。
  • 「資源處理流」:使用此方案,你可以對(duì)資源進(jìn)行包括但不限于 加密 绑谣、 壓縮 等處理流党窜。

當(dāng)然,作為一種方案借宵,目前上述四個(gè)特性可能還過(guò)于抽象幌衣,因此,為了支撐整個(gè)方案壤玫,我準(zhǔn)備了一個(gè)示例 CocosCreator-Build-Encrypt 豁护,作為大家的參考 :


三、Cocos Creator Build Encrypt 方案實(shí)現(xiàn)原理

3.1 原始資源加載 VS 加密資源加載

原始資源的加載欲间,其實(shí)可以簡(jiǎn)化為如下步驟:

運(yùn)行時(shí):讀取原始資源 -> 生成資源對(duì)象

而加密資源的加載择镇,則是在上述基礎(chǔ)上,加入額外的步驟括改,整個(gè)流程大概如下:

運(yùn)行前:讀取原始資源 -> 生成加密內(nèi)容 -> 保存到加密文件
運(yùn)行時(shí):讀取加密文件 -> 解密加密內(nèi)容 -> 生成資源對(duì)象

原理大家可能都有所了解,但是怎么做呢?具體一點(diǎn)嘱能,在 Cocos Creator 上應(yīng)該怎么做呢吝梅?

為此,我們需要先大概了解一下 Cocos Creator 的資源加載流程惹骂。

3.2 Cocos Creator 的資源加載流程

  • 后續(xù)說(shuō)明將以 Cocos Creator 2.3.3 為例進(jìn)行說(shuō)明苏携,2.3.3 和 2.4.0 的資源加載是不一樣的
  • 建議大家下載 Cocos Creator 2.3.3 的 引擎源碼去使用VSCode輔助理解
    git clone git@github.com:cocos-creator/engine.git
    cd engine
    git checkout 2.3.3
    code ../engine
    

事實(shí)上,Cocos Creator 的所有資源加載都是通過(guò) cc.loader 去進(jìn)行的对粪,無(wú)論是動(dòng)態(tài)加載右冻,靜態(tài)加載(場(chǎng)景)等,都是通過(guò) cc.loader 去進(jìn)行加載的著拭。

cc.loader 內(nèi)部的加載實(shí)現(xiàn)是一個(gè) pipe 管道工作流纱扭。每次加載一份資源由最基礎(chǔ)的 3 個(gè)工作流去負(fù)責(zé)整個(gè)加載流程。

  1. assetLoader
  2. downloader
  3. loader

這部分理解儡遮,可以參閱官方文檔 loader 的說(shuō)明

loader

3.3 Cocos Creator Build Encrypt 「全資源支持」「資源處理流」原理

從上述文檔中乳蛾,我們知道有 3 個(gè)管道工作流,但是每個(gè) loader 具體是干什么的鄙币,我們并不知曉肃叶,為了知道這 3 個(gè)工作流的實(shí)際作用,我們需要翻閱源碼

  • 再次建議大家下載 Cocos Creator 2.3.3 的 引擎源碼去使用VSCode輔助理解
    git clone git@github.com:cocos-creator/engine.git
    cd engine
    git checkout 2.3.3
    code ../engine
    

經(jīng)過(guò)翻閱十嘿,可以發(fā)現(xiàn)整個(gè)資源加載的內(nèi)容都在引擎源碼的 cocos2d/core/load-pipeline 目錄下:

CCLoader.js

通過(guò)上面的圖因惭,我們找到了3個(gè) loader 的初始化入口了,在依次翻閱 assetloader绩衷,downloader蹦魔,loader 的相關(guān)實(shí)現(xiàn)之后,我們可以發(fā)現(xiàn)突破口 downloader.js

download.js

總結(jié)一下:

在 cc.loader 的 pipe 管道流的第二個(gè) loader 唇聘,即 downloader 中版姑,Cocos 會(huì)根據(jù)不同資源文件的后綴名,去調(diào)用不同的 download 函數(shù)迟郎,并生成內(nèi)存對(duì)象剥险。

比如:

上述截圖中,png 后綴的文件會(huì)調(diào)用 downloadImage 的函數(shù)宪肖,該函數(shù)最終會(huì)通過(guò) callback(error, data) 函數(shù)返回結(jié)果

  • 如果圖片加載成功過(guò)表制,那么會(huì)返回一個(gè) Image 對(duì)象 callback(null, img);
  • 如果圖片加載失敗,那么會(huì)返回 Error 對(duì)象 callback(error);

再總結(jié)一下:

首先控乾,defaultMap 對(duì)象中么介,羅列了很多資源文件后綴名,并且都有對(duì)應(yīng)的 download 函數(shù)蜕衡。而我們通過(guò)了解 png 的加載邏輯壤短,更是了解到,實(shí)際上 downloadImage 函數(shù)的作用是 將文件下載并讀取轉(zhuǎn)換為內(nèi)存對(duì)象

那如果我們的文件是加密后的文件久脯,那么我們只需要在 downloadImage 函數(shù)中纳胧,讀取文件之后,先進(jìn)行解密帘撰,然后在生成 Image 對(duì)象返回跑慕,那就可以 解決運(yùn)行時(shí)解密的問(wèn)題(讀取加密文件->解密加密內(nèi)容 -> 生成內(nèi)存對(duì)象) 了。

再往外看一下 defaultMap 對(duì)象 摧找,感覺(jué) Cocos Creator 支持的所有的資源核行,我們都可以這樣子來(lái)弄。而這就是我們 Cocos Creator Build Encrypt 方案的特性—— 「全資源支持」 的理論支撐蹬耘!

那么芝雪,新的問(wèn)題來(lái)了,我們應(yīng)該怎么替換不同資源的 download 函數(shù)呢婆赠?

在搜索過(guò)程中绵脯,發(fā)現(xiàn)了很久以前的一個(gè) 帖子 ,帖子中 panda 大大就已經(jīng)羅列了一個(gè)范例:

add downloader

cc.loader 已經(jīng)為我們提供了 addDownloadHandlers 了休里,因此蛆挫,我們可以很方便地替換我們的資源加載方式。

我們以 Cocos Creator 2.3.3 原生平臺(tái)加載的 png 資源為例:

  1. 假設(shè)我們對(duì) Cocos Creator 2.3.3 構(gòu)建原生平臺(tái)后的輸出目錄的所有 png 圖片進(jìn)行加密妙黍,僅僅是轉(zhuǎn)換為 Base64字符串悴侵,并且存放到原png圖片所在目錄的話,參考代碼如下:(具體代碼見(jiàn) CocosCreator-Build-Encrypt 倉(cāng)庫(kù))
handle(): void {
    // 獲取圖片文件
    let imgFilePaths: string[] = [];

    // 獲取指定目錄的所有圖片文件路徑
    this.collectImageFilePaths(buildOutputResDirPath, imgFilePaths);

    // 加密圖片文件
    console.log(`圖片處理:找到 ${imgFilePaths.length} 張?jiān)紙D片`);
    imgFilePaths.forEach((filePath: string) => {
        // 讀取原圖片內(nèi)容
        let fileBuffer: Buffer = fs.readFileSync(filePath);

        // 刪除原圖片資源
        fs.unlinkSync(filePath);

        // 原圖片文件內(nèi)容轉(zhuǎn)換為 Base64 字符串拭嫁,寫(xiě)入到同目錄文件名的 .xxpng 文件中
        fs.writeFileSync(filePath.replace(".png", ".xxpng"), fileBuffer.toString("base64"));
    });
    console.log(`圖片處理:${imgFilePaths.length} 張?jiān)紙D片已加密完成`);
}
  1. 那么可免,對(duì)應(yīng)的解密代碼就可以這樣子寫(xiě):先讀取 .xxxpng 文本,然后將文本解密轉(zhuǎn)換為 Image 對(duì)象做粤,返回 Image 對(duì)象即可:
if (CC_JSB) {
    function downloadText(item) {
        var url = item.url;
        var result = jsb.fileUtils.getStringFromFile(url);
        if (typeof result === "string" && result) {
            return result;
        } else {
            return new Error("Download text failed: " + url);
        }
    }
    cc.loader.addDownloadHandlers({
        png: function (item, callback) {
            // 從定向原圖片地址 為 加密后的文件
            item.url = item.url.replace(".png", ".xxpng");

            let text = downloadText(item);
            if (text instanceof Error) {
                callback(text, null);
            } else {
                // 將圖片文件的文本轉(zhuǎn)換為Image;
                let img = new Image();
                img.src = "data:image/png;base64," + text;

                img.onload = function (info) {
                    callback(null, img);
                };

                img.onerror = function (event) {
                    callback(new Error("load image fail:" + img.src), null);
                }; // Don't return anything to use async loading.
            }
        },
    });
}

當(dāng)然浇借,細(xì)品上面代碼之后,你可能會(huì)有一些問(wèn)題怕品,比如:

Q:第2步中妇垢, downloadText 和 處理 Image 函數(shù),你是怎么知道這樣子寫(xiě)的肉康,我看的源碼中(cocos2d/core/load-pipeline)文本和圖片的處理并不是這樣子的闯估!
A:在 Cocos Creator 2.3.3 打包原生平臺(tái)后,會(huì)生成一個(gè) jsb-adapter 文件夾吼和,在 jsb-adapter/jsb-engine.js 中涨薪,可以看到在原生平臺(tái)上,引擎是重寫(xiě)了資源加載的方式以適配原生平臺(tái)炫乓,參考這里面 png 和 txt 的加載方式刚夺,就可以寫(xiě)出第2步中的代碼了—— 在原生平臺(tái)上讀取文件献丑,并轉(zhuǎn)換為內(nèi)存對(duì)象。

jsb-engine

至此光督,整個(gè)流程上阳距,我們已經(jīng)實(shí)現(xiàn)了資源加解密的流程了,并且理論上可以支持所有的資源哦~

當(dāng)然结借,你完全也可以處理png圖片的時(shí)候

  1. 先進(jìn)行加密
  2. 對(duì)加密內(nèi)容壓縮在寫(xiě)入文件(此壓縮主要用于減少文件體積)

解密時(shí)

  1. 先解壓文件
  2. 在解密內(nèi)容

流式處理,你想怎么處理就怎么處理卒茬。

而這個(gè)也是 Cocos Creator Build Encrypt 的「資源處理流」原理——不僅僅可以加密船老,還可以壓縮等等。

3.4 Cocos Creator Build Encrypt 「跨平臺(tái)」原理

有了上個(gè)章節(jié)的流程后圃酵,我們可以開(kāi)始考慮這個(gè)方案的適用性柳畔,比如:這個(gè)方案能跨平臺(tái)嗎?能跨平臺(tái)到什么程度呢郭赐?

先回顧一下整個(gè)運(yùn)行時(shí)解密的過(guò)程:

運(yùn)行時(shí):讀取加密文件 -> 解密加密內(nèi)容 -> 生成資源對(duì)象

這個(gè)過(guò)程里面的難點(diǎn)在哪里呢薪韩?

  • 解密加密內(nèi)容:這一步不是難點(diǎn)所在,那怕是在不同平臺(tái)上捌锭,我們也能比較好處理俘陷,畢竟加密代碼是我們自己寫(xiě)的加密代碼,對(duì)應(yīng)的解密代碼不是問(wèn)題
  • 生成資源對(duì)象:在不同平臺(tái)上观谦,也不難拉盾,可以參考源碼

那么剩下的就是 讀取加密文件 這一步了,在跨平臺(tái)上豁状,它可能難在哪里呢捉偏?

  1. 文件可能存放在(手機(jī),PC)設(shè)備本地泻红,可以能存放在網(wǎng)絡(luò)上
  2. 在不同平臺(tái)上夭禽,讀取本地文件和網(wǎng)絡(luò)文件的方式可能是不同。比如:
    • 原生Android谊路,iOS上可能是調(diào)用不同的原生讀本地文件接口去讀取文件內(nèi)容讹躯,調(diào)用不同的請(qǐng)求接口去加載網(wǎng)絡(luò)文件
    • 微信小游戲上可能又是不一樣的微信接口方式
    • ...

那么,這些可能的難點(diǎn)要怎么解決呢凶异?

實(shí)際上蜀撑,在上個(gè)章節(jié)的問(wèn)題環(huán)節(jié)中,我們已經(jīng)初步涉及到這問(wèn)題:怎么讀取不同平臺(tái)(Android剩彬,iOS酷麦,微信小游戲等等)的資源?

在上個(gè)章節(jié)中喉恋,我們提及到一個(gè)關(guān)鍵點(diǎn):

在 Cocos Creator 2.3.3 打包原生平臺(tái)后沃饶,會(huì)生成一個(gè) jsb-adapter 文件夾

在這個(gè)理解下母廷,只要我們?cè)谑褂?Cocos Creator 打包指定平臺(tái)后,檢查一下其是否存在相應(yīng)的適配代碼(一般是 jsb-adapter 文件夾)糊肤,參考其中的適配代碼的實(shí)現(xiàn)就可以完成適配該平臺(tái)的讀取文件的實(shí)現(xiàn)了琴昆。

而這就是 Cocos Creator Build Encrypt 「跨平臺(tái)」 原理的理論支撐!

當(dāng)然馆揉,對(duì)應(yīng)到不同版本的 Cocos Creator 业舍,你也可以這樣子參考其輸出的構(gòu)建目錄去進(jìn)行適配。

3.5 Cocos Creator Build Encrypt 「無(wú)侵入」原理

到這里升酣,我們?cè)诨仡櫼幌律厦娴牧鞒滔夏海€缺了一個(gè)很重要的點(diǎn)沒(méi)講:

cc.loader.addDownloadHandlers({
    png: function (item, callback) {
        // ...
    }
}

在什么時(shí)候執(zhí)行上面這段代碼注入呢?

  • 不能在引擎代碼之前注入噩茄,否則腳本不生效
  • 不能在場(chǎng)景加載后才能注入下面,否則可能沒(méi)有覆蓋所有資源加載

那么,剩下答案就是 插件腳本 了 绩聘,在 Cocos Creato 中沥割,存在幾種類型腳本,它們之間的加載順序 如下:

plugin script

那么凿菩,我們只需要將解密的代碼放入到我們的項(xiàng)目机杜,并弄成插件腳本就可以了,Easy~

loader plugin script

至此蓄髓,我們整個(gè)加解密流程是已經(jīng)跑起來(lái)了叉庐,但是完美了嗎?還沒(méi)有会喝。

在將解密代碼導(dǎo)入為插件腳本這一步上陡叠,我們并沒(méi)有做得很好,理由有幾個(gè)點(diǎn):

  1. 每個(gè)項(xiàng)目都需要導(dǎo)入同一份插件腳本肢执,侵入了項(xiàng)目枉阵,并且重復(fù)的工作很乏味
  2. 換個(gè)同學(xué)來(lái)開(kāi)發(fā),肯定會(huì)對(duì)這份插件腳本的代碼有疑問(wèn)预茄,因?yàn)槔锩嬷挥薪饷艽a兴溜,沒(méi)有加密部分(加密部分我們另外寫(xiě)了),代碼不完整耻陕,容易帶來(lái)一些疑問(wèn)拙徽,溝通成本

那么,對(duì)應(yīng)這些問(wèn)題诗宣,最好的解決方案就是「無(wú)侵入」膘怕,讓開(kāi)發(fā)的依舊按照他的開(kāi)發(fā),他看不到也不需要看到整個(gè)資源加解密過(guò)程召庞,只需要提供構(gòu)建目錄岛心,我們對(duì)構(gòu)建目錄進(jìn)行一次加密即可来破。那么又該如何做?

這里需要我們?nèi)チ私庖恍┗镜膯?wèn)題:

Q1. 插件腳本在構(gòu)建后放在哪里忘古?
Q2. 引擎是怎么控制腳本加載順序呢徘禁?具體一點(diǎn)侧到,插件腳本是怎么控制在項(xiàng)目代碼之前加載的呢黔宛?

帶著這兩個(gè)疑問(wèn),我們依舊以 Cocos Creator 2.3.3 打包原生這個(gè)作為例子去了解搔谴。

A1:從下圖可以看到我們構(gòu)建后的插件腳本是放在 src/assets/scripts 目錄下

output

A2:在打包的輸出目錄中

  1. 入口是 main.js (這一點(diǎn)不解釋了)
  2. require 一堆 js 后旦袋,進(jìn)入到 window.boot 函數(shù)骤菠,這里注意一下, jsb-engine.js是先于 window.boot reqiure 的
  3. window.boot 函數(shù)中疤孕,所有的腳本都在 jsList 數(shù)組變量中,并且插件腳本是先于我們的項(xiàng)目腳本的
main.js

javascript plugin

當(dāng)我們了解到這些之后央拖,我們就可以自己去對(duì) Cocos Creator 構(gòu)建輸出后的目錄加入額外的插件腳本了祭阀,步驟如下:

  1. 復(fù)制解密插件腳本到項(xiàng)目構(gòu)建輸出目錄的 src/assets
  2. 修改 main.js ,讓我們的插件腳本先加入到 jsList 變量的前面即可
    image.png

當(dāng)然鲜戒,這兩步操作专控,其實(shí)我們也可以通過(guò)額外的腳本自動(dòng)化,釋放人力遏餐,具體自動(dòng)化代碼可以參考我的示例倉(cāng)庫(kù) CocosCreator-Build-Encrypt

而這伦腐,就是我們 Cocos Creator Build Encrypt 方案的 「無(wú)侵入」 原理了。

三失都、總結(jié)

好了柏蘑,方案完了,這應(yīng)該是一篇長(zhǎng)文粹庞,需要反復(fù)琢磨咳焚,細(xì)節(jié)的地方可能需要在復(fù)習(xí)一下。

需要強(qiáng)調(diào)一下庞溜,這依舊是一個(gè)方案革半。作為一個(gè)方案,它可以改動(dòng)的點(diǎn)太多了流码,比如:

  • 上述例子又官,我們只是以 Cocos Creator 2.3.3 進(jìn)行說(shuō)明,并沒(méi)有對(duì)大改后的 2.4.0 進(jìn)行說(shuō)明漫试,但是根據(jù) 2.4.0 loader
    的文檔和上述理論六敬,但是相信你現(xiàn)在已經(jīng)可以自行適配了
  • 上述例子,我們將 .png 改為了 .xxpng 的密文格式商虐,其實(shí)你完全可以直接覆蓋在 .png 上觉阅,無(wú)需額外弄 .xxpng 后綴(畢竟小游戲平臺(tái)上支持的文件后綴是有限制的)
  • 上述例子崖疤,加解密部分只是為了方便講解,大家完全可以自己重寫(xiě)這部分
  • ...

而我們的例子 CocosCreator-Build-Encrypt 支持的還比較少典勇,但是作為一種方案劫哼,它理論上能支持我上面所說(shuō)的特性:

  • 「無(wú)侵入」
  • 「全資源支持」
  • 「跨平臺(tái)」
  • 「資源處理流」

它依舊需要大家去根據(jù)自己的需求去做完善,但是相信現(xiàn)在的你已經(jīng)知道怎么去弄了割笙。

四权烧、參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市伤溉,隨后出現(xiàn)的幾起案子般码,更是在濱河造成了極大的恐慌,老刑警劉巖乱顾,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件板祝,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡走净,警方通過(guò)查閱死者的電腦和手機(jī)券时,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)伏伯,“玉大人橘洞,你說(shuō)我怎么就攤上這事∷到粒” “怎么了炸枣?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)弄唧。 經(jīng)常有香客問(wèn)我适肠,道長(zhǎng),這世上最難降的妖魔是什么套才? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任迂猴,我火速辦了婚禮,結(jié)果婚禮上背伴,老公的妹妹穿的比我還像新娘沸毁。我一直安慰自己,他們只是感情好傻寂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布息尺。 她就那樣靜靜地躺著,像睡著了一般疾掰。 火紅的嫁衣襯著肌膚如雪搂誉。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天静檬,我揣著相機(jī)與錄音炭懊,去河邊找鬼并级。 笑死,一個(gè)胖子當(dāng)著我的面吹牛侮腹,可吹牛的內(nèi)容都是我干的嘲碧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼父阻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼愈涩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起加矛,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤履婉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后斟览,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體毁腿,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年苛茂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狸棍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡味悄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出塌鸯,到底是詐尸還是另有隱情侍瑟,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布丙猬,位于F島的核電站涨颜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏茧球。R本人自食惡果不足惜庭瑰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抢埋。 院中可真熱鬧弹灭,春花似錦、人聲如沸揪垄。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饥努。三九已至捡鱼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間酷愧,已是汗流浹背驾诈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工缠诅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乍迄。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓管引,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親就乓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汉匙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353