翻牌

注意:此篇文章僅用於研究用途。
朋友的小盾戰(真的很小隻)


其實我還算是蠻喜歡這款遊戲的。
但很矛盾的,我卻不想花錢在那些鮮豔華麗的裝備,與那些消耗速率甚高的消耗品。
多餘的話語就不贅述了,直接進入正題吧。

我還蠻喜歡遊樂場的這位老伯,很多星水啦、磨刀石什麼的都會去找他要,比起直接從商店花還來的划算點。(也就那麼點啦...囧rz)
最近因為想洗技能,所以蠻常找他聊天,不過以前留著的翻牌攻略不知道被我弄去哪了,所以只好隨便亂翻。在翻的過程中,我就一直在想,如果把這個翻牌程式直接抓出來,進行一番的研究,說不定能有甚麼頭緒。
然後!趁現在有一點時間,我稍微把整個東西弄出來看了下。

其實我就在想,這應該是利用swf製成的GUI ,當然輪盤也不例外。
在遊戲中開始翻牌,出現翻牌界面後,便到電腦中去尋找這個swf檔。在這個swf附近當然有一些css、js與jpg檔,這些都是布置這個界面會用到的物件。
而類似「fez_shinkei_last[1].swf」這樣的名稱,就是翻牌的東西了,把它用IE打開,應該可以看到這樣的畫面:



當然此程式的原始設計者是很嚴謹的,隨便點一個牌面就會出現這樣的畫面:


而將這個swf打開(是直接將他解開),可以發現他有做很多exception handling,把裡面的code反覆看了幾次後,一言以蔽之,抽到甚麼牌都是交由伺服器在處理的

但是,有沒有match到牌卻是在本地的機器進行判斷的!
一般來說,這樣的翻牌應該是用以下流程來進行:
(1.)客戶端向伺服器端要求進行翻牌程式,伺服器端傳送翻牌程式到客戶端機器。
(2.)客戶端每點擊一面牌,這面牌的資料由伺服器傳送到客戶端這邊,而伺服器端會記住他送了哪些牌,下次便不會再傳送。
(3.)當點擊次數是偶數次時,客戶端的程式便會判斷最近兩次點擊是否有match到,有的話就傳送伺服器端牌的資料,伺服器端再判斷是哪個牌,便會給予相對的獎勵。
(4.)是否要下一次,或者猜錯,或者全都對了便結束。
其中在第(3.)步,如果今天能夠弄出個小crack,這個東西會使得客戶端不論收到哪樣的牌的資料,皆會傳送match到的訊息給伺服器端,那麼...呵呵嘿嘿嘿。
有興趣的可以去研究一下,當然這裡不建議真的去做出這樣的東西,如果有做出來請通知我(被揍)
以下是他的main code,初步判斷這種應該是java...我沒學過jave,只是感覺它是用這樣的語言。

============================================

// Action script...

// [onClipEvent of sprite 18 in frame 1]
onClipEvent (load)
{
    load_mt.stop();
}
// [onClipEvent of sprite 18 in frame 1]
onClipEvent (enterFrame)
{
    load_mt.gotoAndStop(Math.floor(_root.getBytesLoaded() / _root.getBytesTotal() * 100 + 5.000000E-001) + 1);
    if (Math.floor(_root.getBytesLoaded() / _root.getBytesTotal() * 100 + 5.000000E-001) + 1 == 101)
    {
        _root.gotoAndPlay("game");
    } // end if
}
// [onClipEvent of sprite 37 in frame 18]
on (press)
{
    getURL(_root.back_url, "");
}
// [Action in Frame 1]
function sendandload(send_obj)
{
    _root.dbg_mc.lump.gotoAndPlay("on");
    var _loc2 = new LoadVars();
    for (var _loc4 in send_obj.send_name)
    {
        _loc2[send_obj.send_name[_loc4]] = send_obj.send_val[_loc4];
    } // end of for...in
    var _loc5 = new LoadVars();
    _loc5.onData = function (src)
    {
        if (src == undefined)
        {
            _root.err_set("---", "無法連接到服務器。");
        }
        else
        {
            var _loc2 = new Object();
            _loc2 = _root.sendandload_ck(src);
            if (_loc2.rc_code == "000")
            {
                _root.dbg_mc.lump.gotoAndPlay("off");
                _root[send_obj.rc_function](_loc2);
            }
            else
            {
                _root.err_set(_loc2.rc_code, _loc2.rc_txt);
            } // end else if
        } // end else if
    };
    _loc2.sendAndLoad(send_obj.sendurl, _loc5, send_obj.sendmode);
} // End of the function
function sendandload_ck(str)
{
    var _loc3 = new Object();
    str = unescape(str);
    var _loc2 = str.split("||--Split--||");
    for (var _loc1 = 0; _loc1 < _loc2.length; ++_loc1)
    {
        if (_loc1 % 2 == 1)
        {
            _loc3[_loc2[_loc1 - 1]] = _loc2[_loc1];
        } // end if
    } // end of for
    return (_loc3);
} // End of the function
function send_ck(vars)
{
    if (vars.img_pass)
    {
        img_pass = vars.img_pass;
    }
    else
    {
        _root.err_set("---", "没有找到必要数据img_pass。");
    } // end else if
    if (vars.res_obj)
    {
        var _loc2 = new Array();
        _loc2 = vars.res_obj.split("||--Comma--||");
        _root.load_img(open_id, img_pass + "/" + _loc2[0] + ".png");
        get_item_temp = _loc2[1];
    }
    else
    {
        _root.err_set("---", "没有找到必要数据res_obj。");
    } // end else if
} // End of the function
function randRange(min, max)
{
    var _loc1 = Math.round(Math.random() * (max - min)) + min;
    return (_loc1);
} // End of the function
function load_img(load_id, load_url)
{
    _root.card_set_mc.card_mc_main["card_mc_" + load_id].load_img(load_url);
} // End of the function
function card_id_set()
{
    for (var _loc2 = 0; _loc2 < Max_item * 2; ++_loc2)
    {
        _root.card_set_mc.card_mc_main["card_mc_" + (_loc2 + 1)].i_id = _loc2 + 1;
    } // end of for
} // End of the function
function mekuri_ck()
{
    if (open_flg)
    {
        open_flg = _root.atari_ck();
    }
    else
    {
        if (get_item_temp)
        {
            _root.err_set("---", "含有第一次不需要的数据。");
        } // end if
        open_flg = true;
    } // end else if
    window_flg = 0;
} // End of the function
function atari_ck()
{
    if (get_item_temp)
    {
        if (get_item_temp == "Miss")
        {
            _root.win.pg_flg = "Seizure";
        }
        else
        {
            atari_log = atari_log + (get_item_temp + "\n");
            get_item_temp = "";
            ++open_count;
            if (open_count == Max_item)
            {
                _root.win.pg_flg = "gameend";
            }
            else
            {
                _root.win.pg_flg = "Continuation";
            } // end else if
        } // end else if
        _root.win.gotoAndPlay("win");
        return (false);
    }
    else
    {
        _root.err_set("---", "第二次必须的数据不足。");
    } // end else if
    return (false);
} // End of the function
function card_end()
{
    _root.card_id_set();
    game_start = 1;
} // End of the function
function card_enabled(flg)
{
    for (var _loc2 = 0; _loc2 < Max_item * 2; ++_loc2)
    {
        _root.card_set_mc.card_mc_main["card_mc_" + (_loc2 + 1)].card_atari.useHandCursor = flg;
        _root.card_set_mc.card_mc_main["card_mc_" + (_loc2 + 1)].card_atari.enabled = flg;
        _root.Interruption_btn.useHandCursor = flg;
        _root.Interruption_btn.enabled = flg;
    } // end of for
} // End of the function
function err_set(er_code, er_txt)
{
    _root.er_code = er_code;
    _root.er_txt = er_txt;
    _root.gotoAndPlay("loaderr");
} // End of the function
var main_url = "./breakdown_lot.ashx";
var back_url = "./breakdown_result.ashx";
var main_msd = "POST";
var flm_spd = 24;
var Max_item = 8;
var httpStatus = "";
var httpStatusType = "";
var atas = "";
var img_pass = "";
var get_item_temp = "";
var open_flg = false;
var open_count = 0;
var game_start = 0;
var atari_log = "";
var open_id = 0;
var window_flg = 0;
menu_cm = new ContextMenu();
menu_cm.builtInItems.forward_back = false;
menu_cm.builtInItems.loop = false;
menu_cm.builtInItems.play = false;
menu_cm.builtInItems.print = false;
menu_cm.builtInItems.quality = false;
menu_cm.builtInItems.rewind = false;
menu_cm.builtInItems.zoom = false;
_root.menu = menu_cm;
this.onEnterFrame = function ()
{
    if (game_start)
    {
        if (window_flg)
        {
            _root.card_enabled(false);
        }
        else
        {
            _root.card_enabled(true);
        } // end else if
    }
    else
    {
        _root.card_enabled(false);
    } // end else if
};
// [Action in Frame 6]
stop ();
// [Action in Frame 12]
stop ();
// [Action in Frame 18]
stop ();
============================================


你問能不能夠把伺服器端的程式挖出來?
其實有辦法的,但會這樣說不代表我辦的到,這牽涉到去侵入伺服器竊取資料,弄不好會留下紀錄...而且話又說回來,我的功力也沒這麼深呀OwQ(這才是真的)。



高雄 氷散華
120624

留言

這個網誌中的熱門文章