anodyne/AIR/intra/hsrc/com/amanitadesign/steam/FRESteamWorks.hx

335 lines
9.7 KiB
Haxe

/*
* FRESteamWorks.as
* This file is part of FRESteamWorks.
*
* Created by Ventero<http://github.com/Ventero>
* Copyright(c)2012-2013 Level Up Labs, LLC. All rights reserved.
*/
package com.amanitadesign.steam {
import flash.desktop.NativeProcess;
import flash.desktop.NativeProcessStartupInfo;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.StatusEvent;
import flash.filesystem.File;
import flash.utils.ByteArray<Dynamic>;
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.clearInterval;
import flash.utils.setInterval;
import helper.Achievements;
class FRESteamWorks extends EventDispatcher {
//[Event(name="steam_response", type="com.amanitadesign.steam.SteamEvent")]
private static inline var PATH:String=".local/share/Steam/SteamApps/common/Anodyne/share/APIWrapper";
private var _file:File;
private var _process:NativeProcess;
private var _tm:Int;
private var _error:Bool=false;
public var isReady:Bool=false;
private static inline var AIRSteam_Init:Int=0;
private static inline var AIRSteam_RunCallbacks:Int=1;
private static inline var AIRSteam_RequestStats:Int=2;
private static inline var AIRSteam_SetAchievement:Int=3;
private static inline var AIRSteam_ClearAchievement:Int=4;
private static inline var AIRSteam_IsAchievement:Int=5;
private static inline var AIRSteam_GetStatInt:Int=6;
private static inline var AIRSteam_GetStatFloat:Int=7;
private static inline var AIRSteam_SetStatInt:Int=8;
private static inline var AIRSteam_SetStatFloat:Int=9;
private static inline var AIRSteam_StoreStats:Int=10;
private static inline var AIRSteam_ResetAllStats:Int=11;
private static inline var AIRSteam_GetFileCount:Int=12;
private static inline var AIRSteam_GetFileSize:Int=13;
private static inline var AIRSteam_FileExists:Int=14;
private static inline var AIRSteam_FileWrite:Int=15;
private static inline var AIRSteam_FileRead:Int=16;
private static inline var AIRSteam_FileDelete:Int=17;
private static inline var AIRSteam_IsCloudEnabledForApp:Int=18;
private static inline var AIRSteam_SetCloudEnabledForApp:Int=19;
private static inline var AIRSteam_GetUserID:Int=20;
private static inline var AIRSteam_GetPersonaName:Int=21;
private static inline var AIRSteam_UseCrashHandler:Int=22;
public function new(target:IEventDispatcher=null){
try {
_file=File.userDirectory.resolvePath(PATH);
Achievements.DEBUG_TEXT +="Found file at\n" + _file.nativePath +"\n";
Achievements.DEBUG_TEXT +=_file.size.toString()+ " bytes\n";
} catch(e:Dynamic){
Achievements.DEBUG_TEXT +="COULDN'T FIND FILE";
}
_process=new NativeProcess();
_process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, eventDispatched);
_process.addEventListener(IOErrorEvent.STANDARD_INPUT_IO_ERROR, errorCallback);
super(target);
}
public function dispose():Void {
if(_process.running){
_process.closeInput();
_process.exit();
}
clearInterval(_tm);
isReady=false;
}
private function startProcess():Void {
var startupInfo:NativeProcessStartupInfo=new NativeProcessStartupInfo();
startupInfo.executable=_file;
_process.start(startupInfo);
}
public function init():Bool {
trace("hi")
trace(Achievements.DEBUG_TEXT);
Achievements.DEBUG_TEXT +="Sanity check...";
trace(Achievements.DEBUG_TEXT);
if(_file==null || !_file.exists)return false;
Achievements.DEBUG_TEXT +="got file\n";
startProcess();
if(!_process.running){
Achievements.DEBUG_TEXT +="Process not running\n";
return false;
}
if(!callWrapper(AIRSteam_Init))return false;
isReady=readBoolResponse();
if(isReady)_tm=setInterval(runCallbacks, 100);
Achievements.DEBUG_TEXT +="ready? " + isReady.toString()+ "\n";
return isReady;
}
private function errorCallback(e:IOErrorEvent):Void {
_error=true;
// the process doesn't accept our input anymore, so just stop it
clearInterval(_tm);
if(_process.running){
try {
_process.closeInput();
} catch(e:Dynamic){
// no-op
}
_process.exit();
}
}
private function callWrapper(funcName:Int, params:Array<Dynamic>=null):Bool {
_error=false;
if(!_process.running){
Achievements.DEBUG_TEXT +="wrapper call fail\n";
return false;
}
var stdin:IDataOutput=_process.standardInput;
stdin.writeUTFBytes(funcName + "\n");
if(params){
for(i in 0...params.lengthi){
if(params[i] is ByteArray){
var length:Int=params[i].length;
// length + 1 for the added newline
stdin.writeUTFBytes(String(length + 1)+ "\n");
stdin.writeBytes(params[i]);
stdin.writeUTFBytes("\n");
} else {
stdin.writeUTFBytes(String(params[i])+ "\n");
}
}
}
return !_error;
}
private function waitForData(output:IDataInput):Int {
while(!output.bytesAvailable){
// wait
if(!_process.running)return 0;
}
return output.bytesAvailable;
}
private function readBoolResponse():Bool {
if(!_process.running)return false;
var stdout:IDataInput=_process.standardOutput;
var avail:Int=waitForData(stdout);
var response:String=stdout.readUTFBytes(1);
Achievements.DEBUG_TEXT +="bool resp:" + response.toString()+ "\n";
return(response=="t");
}
private function readIntResponse():Int {
if(!_process.running)return 0;
var stdout:IDataInput=_process.standardOutput;
var avail:Int=waitForData(stdout);
var response:String=stdout.readUTFBytes(avail);
return parseInt(response, 10);
}
private function readFloatResponse():Float {
if(!_process.running)return 0.0;
var stdout:IDataInput=_process.standardOutput;
var avail:Int=waitForData(stdout);
var response:String=stdout.readUTFBytes(avail)
return parseFloat(response);
}
private function readStringResponse():String {
if(!_process.running)return "";
var stdout:IDataInput=_process.standardOutput;
var avail:Int=waitForData(stdout);
var response:String=stdout.readUTFBytes(avail)
return response;
}
private function eventDispatched(e:ProgressEvent):Void {
var stderr:IDataInput=_process.standardError;
var avail:Int=stderr.bytesAvailable;
var data:String=stderr.readUTFBytes(avail);
var pattern:RegExp=/__event__<(\d+),(\d+)>/g;
var result:Dynamic;
while((result=pattern.exec(data))){
var req_type:Int=new Std.int(result[1]);
var response:Int=new Std.int(result[2]);
var steamEvent:SteamEvent=new SteamEvent(SteamEvent.STEAM_RESPONSE, req_type, response);
dispatchEvent(steamEvent);
}
}
public function requestStats():Bool {
if(!callWrapper(AIRSteam_RequestStats))return false;
return readBoolResponse();
}
public function runCallbacks():Bool {
if(!callWrapper(AIRSteam_RunCallbacks))return false;
return true;
}
public function getUserID():String {
if(!callWrapper(AIRSteam_GetUserID))return "";
return readStringResponse();
}
public function getPersonaName():String {
if(!callWrapper(AIRSteam_GetPersonaName))return "";
return readStringResponse();
}
public function useCrashHandler(appID:Int, version:String, date:String, time:String):Bool {
if(!callWrapper(AIRSteam_UseCrashHandler, [appID, version, date, time]))return false;
return readBoolResponse();
}
public function setAchievement(id:String):Bool {
if(!callWrapper(AIRSteam_SetAchievement, [id]))return false;
return readBoolResponse();
}
public function clearAchievement(id:String):Bool {
if(!callWrapper(AIRSteam_ClearAchievement, [id]))return false;
return readBoolResponse();
}
public function isAchievement(id:String):Bool {
if(!callWrapper(AIRSteam_IsAchievement, [id]))return false;
return readBoolResponse();
}
public function getStatInt(id:String):Int {
if(!callWrapper(AIRSteam_GetStatInt, [id]))return 0;
return readIntResponse();
}
public function getStatFloat(id:String):Float {
if(!callWrapper(AIRSteam_GetStatFloat, [id]))return 0.0;
return readFloatResponse();
}
public function setStatInt(id:String, value:Int):Bool {
if(!callWrapper(AIRSteam_SetStatInt, [id, value]))return false;
return readBoolResponse();
}
public function setStatFloat(id:String, value:Float):Bool {
if(!callWrapper(AIRSteam_SetStatFloat, [id, value]))return false;
return readBoolResponse();
}
public function storeStats():Bool {
if(!callWrapper(AIRSteam_StoreStats))return false;
return readBoolResponse();
}
public function resetAllStats(bAchievementsToo:Bool):Bool {
if(!callWrapper(AIRSteam_ResetAllStats, [bAchievementsToo]))return false;
return readBoolResponse();
}
public function getFileCount():Int {
if(!callWrapper(AIRSteam_GetFileCount))return 0;
return readIntResponse();
}
public function getFileSize(fileName:String):Int {
if(!callWrapper(AIRSteam_GetFileSize, [fileName]))return 0;
return readIntResponse();
}
public function fileExists(fileName:String):Bool {
if(!callWrapper(AIRSteam_FileExists, [fileName]))return false;
return readBoolResponse();
}
public function fileWrite(fileName:String, data:ByteArray):Bool {
if(!callWrapper(AIRSteam_FileWrite, [fileName, data]))return false;
return readBoolResponse();
}
public function fileRead(fileName:String, data:ByteArray):Bool {
if(!callWrapper(AIRSteam_FileRead, [fileName]))return false;
var success:Bool=readBoolResponse();
if(success){
var content:String=readStringResponse();
data.writeUTFBytes(content);
data.position=0;
}
return success;
}
public function fileDelete(fileName:String):Bool {
if(!callWrapper(AIRSteam_FileDelete, [fileName]))return false;
return readBoolResponse();
}
public function isCloudEnabledForApp():Bool {
if(!callWrapper(AIRSteam_IsCloudEnabledForApp))return false;
return readBoolResponse();
}
public function setCloudEnabledForApp(enabled:Bool):Bool {
if(!callWrapper(AIRSteam_SetCloudEnabledForApp, [enabled]))return false;
return readBoolResponse();
}
}