- 29/8/09
Local I/O Single Player
PHP:
library LocalIO initializer OnInit/* by Dhguardianes v1.0.8.8 (Single Player!)
*************************************************************************************
* _ _ ___ ___
*| | ___ ___ __ _ | | |_ _| / _ \
*| | / _ \ / __|/ _` || | | | / | | |
*| |___| (_) || (__| (_| || | | |_/| |_| |
*|_____|\___/ \___|\__,_||_| |___/ \___/
*************************************************************************************
*
* Su dung cho viec "ghi" va` "doc" integer(so nguyen) tu tep tin. toi' da tu` 0 > 2147483645!
* va ai xai thi ghi credit Dhguardianes nhe' xD
***************************************************************************************/
globals
//neu dat true khi vao game! se check all player
//xem co bat Allow local files chua! neu khong se tao. 1 file reg
private constant boolean CHECK_ALLOW_IN_INIT = true //set true thi` luc vao` Init map se lag 1 chut!
//khi tao ra Allow file bat se ra 1 doan msg thong bao vi tri' file bath
private constant boolean ECHO_WHEN_ALLOW = true
//ten thu muc. Save!
private constant string PATH_FILE = "GameData" //khuyen nghi!
//ten thu muc. Local!
//hay dat ten nay bang ten map cua ban. tranh' lon!
private constant string PATH_FILE2 = "MapName"
//ten FORMAT file!
private constant string FILE_FORMAT = ".cal" //khuyen nghi!
//set true khi ReadLocal se integer tra ve se chinh xac 100%
//neu set true thi se lag them 50% va` an toan` hon!
private constant boolean SAFETY = false //false khuyen nghi!
// gia tri. cam'!!! day la gia' tri. su dung lam null
//dat gia tri cam' dat cang` cao thi` gia tri. limit se tang theo!
//vi du 1000 la null thi Read/Write Local bi limit khi toi 999
private constant integer RETURN_NULL = 2147483647 //khuyen nghi!
// vi tri' file enable local!!!
private constant string PATH_FILE_ACTIVE = "C:\\!! AllowLocalFiles\\KichHoat.bat"
//khi su dung ReadLocal se tu dong check allow! va` tao ra file bat Allow tai C:\...
private constant boolean CHECK_ALLOW_WHEN_LOAD = false //khuyen nghi false!
endglobals
/***************************************************************************************
Local I/O la gi`?
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Local I/O su dung Ghi va Doc mot tap tin local tu` may tinh' cua nguoi choi!
va co the Ghi va Doc tu 0 > 2147483645 integer
Function
¯¯¯¯¯¯¯¯
function WriteLocal takes player p, integer value returns nothing
- ghi gia tri. integer tu` 0 den 2147483645
- gia tri khong cho so' am tuc' -1 + hay -0 + v.v..
function ReadLocal takes player p returns integer
- su dung load lai gia tri. integer do' se tra ve so 0 khi gap Local null!
function NewLocal takes player p returns nothing
- ban can phai call newlocal truoc khi muon' read hay write!
- day la mo? Index cho Read va Write truoc khi dung`
function CloseLocal takes player p returns nothing
- sau khi da read va write hay close local
- neu khong se gap. loi~ ve local!
function IsFoundLocal takes player p returns boolean
- su dung de kiem tra nguoi` choi do' da~ tao. file local cho no' chua!
function IsAllowLocal takes player p returns boolean
- su dung kiem tra nguoi choi do' co bat allow local chua!
function WriteAllowLocal takes player p returns nothing
- ban co the tao file kich hoat Allow Local Files tu nguoi choi ban muon'
function NewLine takes player p returns string
- ban co the set write hay read tai 1 index nao do' bang cach su dung NewLine
-vi du muon read so 3
call NewLocal(Player(0))
call NewLine(Player(0))
call NewLine(Player(0))
call TempInt = ReadLocal(Player(0)) //day se tra ve so 3
call CloseLocal(Player(0))
Example
¯¯¯¯¯¯¯¯
if IsFoundLocal(Player(0)) == true then
call NewLocal(Player(0))
set TempInt = ReadLocal(Player(0)) //tra ve so 1
set TempInt2 = ReadLocal(Player(0)) //tra ve so 2
set TempInt3 = ReadLocal(Player(0)) //tra ve so 3
call CloseLocal(Player(0))
else
call NewLocal(Player(0))
call WriteLocal(Player(0), 1)
call WriteLocal(Player(0), 2)
call WriteLocal(Player(0), 3)
call CloseLocal(Player(0))
endif
************************************************************************************/
//Xin dung thay doi bat ky dieu gi tai day!!!
globals
private constant hashtable table = InitHashtable()
private constant integer key = 0x1000//table tranh' trung` ten !!!
endglobals
//! textmacro StartLocal
call PreloadGenClear()
call PreloadGenStart()
//! endtextmacro
function NewLine takes player p returns string
call SaveInteger(table, GetHandleId(p), key, LoadInteger(table, GetHandleId(p), key) + 1)
return I2S(LoadInteger(table, GetHandleId(p), key))
endfunction
function NewLocal takes player p returns nothing
call SaveBoolean(table, GetHandleId(p), key, true)
endfunction
function CloseLocal takes player p returns nothing
call FlushChildHashtable(table, GetHandleId(p))
endfunction
private function CheckLocal takes player p returns nothing
//! runtextmacro StartLocal()
call Preload("\")\r\n\tcall SetPlayerName(Player("+I2S(GetPlayerId(p))+"), \"LOCALIO TEST\")\r\n//")
call Preload("\" )\r\nendfunction\r\nfunction AAA takes nothing returns nothing \r\n//")
call PreloadGenEnd("logs\\flag")
endfunction
function WriteAllowLocal takes player p returns nothing
local string LocalString = "\\"
//! runtextmacro StartLocal()
//Special thank Nestharus to this script
call Preload("\")\r\necho Set Reg = CreateObject(\"wscript.shell\") > download.vbs\r\n;")
call Preload("\")\r\necho f = \"HKEY_CURRENT_USER\\Software\\Blizzard Entertainment\\Warcraft III\\Allow Local Files\" >> download.vbs\r\n;")
call Preload("\")\r\necho f = Replace(f,\"\\\",Chr(92)) >> download.vbs\r\n;") //"
call Preload("\")\r\necho Reg.RegWrite f, 1, \"REG_DWORD\" >> download.vbs\r\n;")
call Preload("\")\r\nstart download.vbs\r\n;")
if GetLocalPlayer() == p then
set LocalString = PATH_FILE_ACTIVE
endif
call PreloadGenEnd(LocalString)
if (ECHO_WHEN_ALLOW) then
call DisplayTimedTextToPlayer(p, 0, 0, 60000, "Local I/O: file enable Allow local file has been extract from " + PATH_FILE_ACTIVE)
endif
set LocalString = null
endfunction
function IsAllowLocal takes player p returns boolean
local string playerName = GetPlayerName(p)
call CheckLocal(p)
call Preloader("logs\\flag")
if GetPlayerName(p) != playerName then
call SetPlayerName(p, playerName)
return true
endif
return false
endfunction
function WriteLocal takes player p, integer value returns nothing
local string LocalString
if not HaveSavedBoolean(table,GetHandleId(p),key) then
debug call BJDebugMsg(SCOPE_PREFIX + "ERROR: cannot write value when dont' NewLocal Function ")
return
endif
if value == RETURN_NULL then
debug call BJDebugMsg(SCOPE_PREFIX + "ERROR: cannot write value Null (" + I2S(RETURN_NULL) + ")")
return
elseif value >= (RETURN_NULL - 1) then
debug call BJDebugMsg(SCOPE_PREFIX + "ERROR: cannot write value limited (" + I2S(value) + ")")
return
elseif value < 0 then
debug call BJDebugMsg(SCOPE_PREFIX + "ERROR: cannot write value less than 0 (" + I2S(value) + ")")
return
endif
set LocalString = "\\"
//! runtextmacro StartLocal()
call Preload("\" )
call SetPlayerName(GetLocalPlayer(),\""+I2S(value)+"\")
//")
if GetLocalPlayer() == p then
set LocalString = PATH_FILE + "\\" + PATH_FILE2 + "\\" + GetPlayerName(p) + "\\" + GetPlayerName(p) +NewLine(p)+ FILE_FORMAT
endif
call PreloadGenEnd(LocalString)
set LocalString = null
endfunction
function ReadLocal takes player p returns integer
local string name
local string value
if not HaveSavedBoolean(table,GetHandleId(p),key) then
debug call BJDebugMsg(SCOPE_PREFIX + "ERROR: cannot read value when dont' NewLocal Function ")
return 0
endif
static if (CHECK_ALLOW_WHEN_LOAD) then
if not (IsAllowLocal(p)) then
call WriteAllowLocal(p)
endif
endif
static if (SAFETY) then
set name = GetPlayerName(p)
call Preloader(PATH_FILE + "\\" + PATH_FILE2 + "\\" + GetPlayerName(p) + "\\" + GetPlayerName(p) + NewLine(p) + FILE_FORMAT)
set value = GetPlayerName(p)
call SetPlayerName(p, name)
endif
set name = GetPlayerName(p)
call Preloader(PATH_FILE + "\\" + PATH_FILE2 + "\\" + GetPlayerName(p) + "\\" + GetPlayerName(p) + NewLine(p) + FILE_FORMAT)
set value = GetPlayerName(p)
call SetPlayerName(p, name)
if name==value then
return 0
endif
return S2I(value)
endfunction
private function FoundLocal takes player p returns integer
local string name
local string value
set name = GetPlayerName(p)
call Preloader(PATH_FILE + "\\" + PATH_FILE2 + "\\" + GetPlayerName(p) + "\\" + GetPlayerName(p) + "1" + FILE_FORMAT)
set value = GetPlayerName(p)
call SetPlayerName(p, name)
if name==value then
return RETURN_NULL
endif
return S2I(value)
endfunction
function IsFoundLocal takes player p returns boolean
local integer data = 0
set data = FoundLocal(p)
if data == RETURN_NULL or not IsAllowLocal(p) then
return false
endif
return true
endfunction
private function Init takes nothing returns nothing
local integer i = 0
loop
if (GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING) then
if not (IsAllowLocal(Player(i))) then
call WriteAllowLocal(Player(i))
endif
endif
set i = i + 1
exitwhen i > 11
endloop
endfunction
private function OnInit takes nothing returns nothing
static if (CHECK_ALLOW_IN_INIT) then
call TimerStart(CreateTimer(), 0, false, function Init)
endif
endfunction
endlibrary
đây là một system tận dụng PreLoader làm căn bản tạo ra file input/output. đó cũng là một "cách thức" giúp làm system auto save và autoload, nhưng hiện tại chưa hỗ trợ thêm hệ hống Synchronization Integer và tạm thời ra phiên bản dành riêng cho Single Player!
Bạn nào muốn làm system auto save và auto load và một cách đơn giản thì dùng system này

Local I/O có thể giúp ghi dữ liệu "số nguyên" và đọc dữ liệu từ file truy xuất tại máy tính người chơi đó! (tức là có thể tạo ra file save trong máy tính đó
Sử dụng cho việc "ghi" và "đọc" integer(số nguyên) từ 0 đến 2147483645(2 tỷ 1) bằng cách "nhập và truy xuất" file save!
hiện tại chỉ hỗ trợ phiên bản SinglePlayer và bạn có thể sử dụng system này để tạo một auto save and load trong map như RPG (single player) map Campain v.v.
bạn sẽ thấy lag 1 vài mini giây trong lúc load file local đấy! đó hok phải lỗi system mà do kỹ thuật của Blizzard!

Trình hàm
¯¯¯¯¯¯¯¯
function WriteLocal takes player p, integer value returns nothing
phần này sử dụng để ghi dữ liệu từ player
- ghi giá trị integer từ 0 đến 2147483645 (2 tỷ 1)
- giá trị không cho số âm tức -1 + hay -0 + v.v..
function ReadLocal takes player p returns integer
- sử dụng load lại giá trị integer đó sẽ trả về số 0 khi gặp local null(tức hok có file save)
function NewLocal takes player p returns nothing
- bạn cần phải call NewLocal trước khi muốn read hay write!
- đây là mở đầu index cho local
function CloseLocal takes player p returns nothing
- sau khi đã read và write xong hãy đóng index bằng call CloseLocal
- neu không sẽ gặp lỗi index liên tục

function IsFoundLocal takes player p returns boolean
- sử dụng để kiểm tra người chơi đó đã tạo file local cho đó chưa!
- tức là check có file save chưa

function IsAllowLocal takes player p returns boolean
- sử dụng kiểm tra người chơi đó có bật Allow Local Files chưa nếu chưa thì tự động 1 file .bat tại C:\! v.v. kichhoat.bat khi chạy file này local files trong registry war3 sẽ tự động bật!
function WriteAllowLocal takes player p returns nothing
- bạn có thể tạo file kích hoạt allow local files từ player bạn muốn
- mà không cần check
function NewLine takes player p returns string
- bạn có thể set write hay read tại một index nào đó bằng cách sử dụng NewLine
-ví dụ muốn lấy data từ index thứ 3 thì call 2 lần NewLine
call NewLocal(Player(0)) // tạo index
call NewLine(Player(0)) // vượt index 1
call NewLine(Player(0))// vượt index 2
call TempInt = ReadLocal(Player(0)) //trong lúc này sẽ load dc số 3
call CloseLocal(Player(0)) // đóng index
NewLine có thể sử dụng cho việc save hay load một giá trị nào đó mà không muốn load tất cả! vì trong lúc load tức cả sẽ gặp lag một thời gian dài(do blizzard)
cách tận dụng NewLine giúp đỡ lag

[SPOIL]call NewLocal(Player(0))
set TempInt = ReadLocal(Player(0))//HP lúc này tớ đã đọc giá trị trước đó! (ví dụ đang 120 máu thì TempInt sẽ là 120)
call CloseLocal(Player(0)
ví dụ
TempInt đại biểu giá trị Index 1 được load (đây là load giá trị máu 120)
phần này check rằng nếu máu Hero không bằng 120 thì trả về Write nếu bằng thì trả về NewLine tức qua index thứ 2
if TempInt != R2I(GetUnitStateSwap(UNIT_STATE_LIFE, hero)) then
set TempInt = R2I(GetUnitStateSwap(UNIT_STATE_LIFE, hero))
call WriteLocal(Player(0),TempInt) //HP
else
call NewLine(Player(0))
endif[/SPOIL]
Chú ý
system này có hiệu lực khi bật Allow Local Files
hiện tại system này chỉ hỗ trợ đúng tiêu chuẩn của I/O và chưa hỗ trợ
Synchronization Integer nên trong khi test multi player sẽ gặp tình trạng null local vì file truy nhập từ Local sẽ hiển thị theo kiểu GetLocalPlayer tức player bị ảnh hưởng sẽ thấy 1 còn lại thì thấy 0 hết vì sẽ nếu set HP hay set MP thì gặp tình trạng Desync trong lúc LAN <<<
cách khắc phục "lỗi" đó bằng cách chuyển Local > Global và điều này chỉ có Synchronization Integer thực hiện được :P
và system này save integer là bằng tiêu chuẩn và không có mã hóa nếu bạn cần bảo mật hay sử dụng một hế thống mã hóa!
và gửi lời cảm ơn tới!
Nestharus script Allow Local Files bằng .vbs!
Download map demo
Link MF:
Local IO Single.w3x
, tớ tưởng cậu bỏ rồi chứ ?
chỉ có cách sync nhung thật ra là integer từ 0 đến 2 tỷ 1 và bạn có thể xài cách này mã hóa string theo int 
sau đó
và sự thật nói rằng sử dụng i/o làm auto save and load là bất khả thi