2017年5月

AutoHotKey聚币网行情显示

头几天一哥们跟我说,让我给开发一个软件,可以在桌面右下角显示指定山寨币的最新行情,我说可以。因为我之前有用AutoHotKey写过其他平台的行情获取工具,所以这里我也用AutoHotKey.

我用AutoHotKey其实很少,以前上学的时候用这个工具写过剑灵的一些个出招脚本,就是卡刀啥的?有点忘记了。

知识掌握:

AutoHotKey : 网络访问,Gui使用,流程

编写思路:

首先要获取到聚币网的行情数据,我以无限币作为例子,进入无限币的交易页面后,F12查看Network标签页,发现有两个Ajax数据,一会又来两个相同地址不同t参数的。很显然,这就是我们要获取的数据,那具体是哪个呢?右键对应的数据行,Open in new tab,然后知道了最新的价格是由trades这个接口来的。

另外行情接口返回的是json格式的,我们需要一个json的解析库,见我前一篇博文。https://www.djc8.cn/archives/autohotkey-json-library.html

图片

很好,知道了这些数据后,就开始撸了吧。

AutoHotKey这个工具下载下来:https://autohotkey.com

解压放到某个目录。

新建文件:自动显示ifc指数.ahk

代码如下:

#Include json.ahk

CustomColor = EEAA99 

Gui +LastFound +AlwaysOnTop -Caption +ToolWindow 

Gui, Color, %CustomColor%

Gui, Font, s10

Gui, Add, Text,vMyText cLime,'                                      '

WinSet, TransColor, %CustomColor% 150

SetTimer, UpdateOSD, 5000

Gosub, UpdateOSD

Gui, Show, x1440 y1050 w300 h20 NoActivate

return


UpdateOSD:

Gui +LastFound +AlwaysOnTop -Caption +ToolWindow 

oHttp := ComObjCreate("WinHttp.Winhttprequest.5.1")

FormatTime, OutputVar, ddddMMMMd,yyyyMMddhhmmss

OutputVar:="https://www.jubi.com/coin/ifc/trades?t=" . OutputVar

oHttp.open("GET",OutputVar)

DogStrNewStr:="Net lost"

try

{

oHttp.send()

parsed := JSON.Load(oHttp.responseText)

DogStrNewStr:=parsed.sell[1][1]

}

catch e

{

PutGuiCtl(%e%)

return

}

PutGuiCtl(DogStrNewStr)

return


PutGuiCtl(string){

GuiControl,, MyText,  % string 

return

}

在右下角显示如下:
图片

Autohotkey json库

最近在用Autohotkey写一个自动获取某比特币交易网站数据的小工具。该工具实时从交易网站获取最新的某个山寨币的最新市值,由于该交易网站的api接口使用json返回数据,所以我要找一个json的库。

很幸运,强大的Autohotkey早有人提供了这个库。

https://github.com/cocobelgica/AutoHotkey-JSON

不知道是我孤陋寡闻还是啥的,我看了下这个git仓库,居然是大神级别,里面很多Autohotkey的支持库,比如解压缩,mail,高亮编辑器啥的。

咳咳。。。

为了以后好找我就直接复制过来了。

/**    
 * Lib: JSON.ahk    
 *     JSON lib for AutoHotkey.    
 * Version:    
 *     v2.1.3 [updated 04/18/2016 (MM/DD/YYYY)]    
 * License:    
 *     WTFPL [http://wtfpl.net/]    
 * Requirements:    
 *     Latest version of AutoHotkey (v1.1+ or v2.0-a+)    
 * Installation:    
 *     Use #Include JSON.ahk or copy into a function library folder and then    
 *     use #Include <JSON>    
 * Links:    
 *     GitHub:     - https://github.com/cocobelgica/AutoHotkey-JSON    
 *     Forum Topic - http://goo.gl/r0zI8t    
 *     Email:      - cocobelgica <at> gmail <dot> com    
 */    
/**    
 * Class: JSON    
 *     The JSON object contains methods for parsing JSON and converting values    
 *     to JSON. Callable - NO; Instantiable - YES; Subclassable - YES;    
 *     Nestable(via #Include) - NO.    
 * Methods:    
 *     Load() - see relevant documentation before method definition header    
 *     Dump() - see relevant documentation before method definition header    
 */    
class JSON    
{    
    /**    
     * Method: Load    
     *     Parses a JSON string into an AHK value    
     * Syntax:    
     *     value := JSON.Load( text [, reviver ] )    
     * Parameter(s):    
     *     value      [retval] - parsed value    
     *     text    [in, ByRef] - JSON formatted string    
     *     reviver   [in, opt] - function object, similar to JavaScript's    
     *                           JSON.parse() 'reviver' parameter    
     */    
    class Load extends JSON.Functor    
    {    
        Call(self, ByRef text, reviver:="")    
        {    
            this.rev := IsObject(reviver) ? reviver : false    
        ; Object keys(and array indices) are temporarily stored in arrays so that    
        ; we can enumerate them in the order they appear in the document/text instead    
        ; of alphabetically. Skip if no reviver function is specified.    
            this.keys := this.rev ? {} : false    
            static quot := Chr(34), bashq := "\" . quot    
            , json_value := quot . "{[01234567890-tfn"    
            , json_value_or_array_closing := quot . "{[]01234567890-tfn"    
            , object_key_or_object_closing := quot . "}"    
            key := ""    
            is_key := false    
            root := {}    
            stack := [root]    
            next := json_value    
            pos := 0    
            while ((ch := SubStr(text, ++pos, 1)) != "") {    
                if InStr(" `t`r`n", ch)    
                    continue    
                if !InStr(next, ch, 1)    
                    this.ParseError(next, text, pos)    
                holder := stack[1]    
                is_array := holder.IsArray    
                if InStr(",:", ch) {    
                    next := (is_key := !is_array && ch == ",") ? quot : json_value    
                } else if InStr("}]", ch) {    
                    ObjRemoveAt(stack, 1)    
                    next := stack[1]==root ? "" : stack[1].IsArray ? ",]" : ",}"    
                } else {    
                    if InStr("{[", ch) {    
                    ; Check if Array() is overridden and if its return value has    
                    ; the 'IsArray' property. If so, Array() will be called normally,    
                    ; otherwise, use a custom base object for arrays    
                        static json_array := Func("Array").IsBuiltIn || ![].IsArray ? {IsArray: true} : 0    
                    ; sacrifice readability for minor(actually negligible) performance gain    
                        (ch == "{")    
                            ? ( is_key := true    
                            , value := {}    
                            , next := object_key_or_object_closing )    
                        ; ch == "["    
                            : ( value := json_array ? new json_array : []    
                            , next := json_value_or_array_closing )    
                        ObjInsertAt(stack, 1, value)    
                        if (this.keys)    
                            this.keys[value] := []    
                    } else {    
                        if (ch == quot) {    
                            i := pos    
                            while (i := InStr(text, quot,, i+1)) {    
                                value := StrReplace(SubStr(text, pos+1, i-pos-1), "\\", "\u005c")    
                                static tail := A_AhkVersion<"2" ? 0 : -1    
                                if (SubStr(value, tail) != "\")    
                                    break    
                            }    
                            if (!i)    
                                this.ParseError("'", text, pos)    
                            value := StrReplace(value,  "\/",  "/")    
                            , value := StrReplace(value, bashq, quot)    
                            , value := StrReplace(value,  "\b", "`b")    
                            , value := StrReplace(value,  "\f", "`f")    
                            , value := StrReplace(value,  "\n", "`n")    
                            , value := StrReplace(value,  "\r", "`r")    
                            , value := StrReplace(value,  "\t", "`t")    
                            pos := i ; update pos    
                            i := 0    
                            while (i := InStr(value, "\",, i+1)) {    
                                if !(SubStr(value, i+1, 1) == "u")    
                                    this.ParseError("\", text, pos - StrLen(SubStr(value, i+1)))    
                                uffff := Abs("0x" . SubStr(value, i+2, 4))    
                                if (A_IsUnicode || uffff < 0x100)    
                                    value := SubStr(value, 1, i-1) . Chr(uffff) . SubStr(value, i+6)    
                            }    
                            if (is_key) {    
                                key := value, next := ":"    
                                continue    
                            }    
                        } else {    
                            value := SubStr(text, pos, i := RegExMatch(text, "[\]\},\s]|$",, pos)-pos)    
                            static number := "number", integer :="integer"    
                            if value is %number%    
                            {    
                                if value is %integer%    
                                    value += 0    
                            }    
                            else if (value == "true" || value == "false")    
                                value := %value% + 0    
                            else if (value == "null")    
                                value := ""    
                            else    
                            ; we can do more here to pinpoint the actual culprit    
                            ; but that's just too much extra work.    
                                this.ParseError(next, text, pos, i)    
                            pos += i-1    
                        }    
                        next := holder==root ? "" : is_array ? ",]" : ",}"    
                    } ; If InStr("{[", ch) { ... } else    
                    is_array? key := ObjPush(holder, value) : holder[key] := value    
                    if (this.keys && this.keys.HasKey(holder))    
                        this.keys[holder].Push(key)    
                }    
            } ; while ( ... )    
            return this.rev ? this.Walk(root, "") : root[""]    
        }    
        ParseError(expect, ByRef text, pos, len:=1)    
        {    
            static quot := Chr(34), qurly := quot . "}"    
            line := StrSplit(SubStr(text, 1, pos), "`n", "`r").Length()    
            col := pos - InStr(text, "`n",, -(StrLen(text)-pos+1))    
            msg := Format("{1}`n`nLine:`t{2}`nCol:`t{3}`nChar:`t{4}"    
            ,     (expect == "")     ? "Extra data"    
            : (expect == "'")    ? "Unterminated string starting at"    
            : (expect == "\")    ? "Invalid \escape"    
            : (expect == ":")    ? "Expecting ':' delimiter"    
            : (expect == quot)   ? "Expecting object key enclosed in double quotes"    
            : (expect == qurly)  ? "Expecting object key enclosed in double quotes or object closing '}'"    
            : (expect == ",}")   ? "Expecting ',' delimiter or object closing '}'"    
            : (expect == ",]")   ? "Expecting ',' delimiter or array closing ']'"    
            : InStr(expect, "]") ? "Expecting JSON value or array closing ']'"    
            :                      "Expecting JSON value(string, number, true, false, null, object or array)"    
            , line, col, pos)    
            static offset := A_AhkVersion<"2" ? -3 : -4    
            throw Exception(msg, offset, SubStr(text, pos, len))    
        }    
        Walk(holder, key)    
        {    
            value := holder[key]    
            if IsObject(value) {    
                for i, k in this.keys[value] {    
                    ; check if ObjHasKey(value, k) ??    
                    v := this.Walk(value, k)    
                    if (v != JSON.Undefined)    
                        value[k] := v    
                    else    
                        ObjDelete(value, k)    
                }    
            }    
            return this.rev.Call(holder, key, value)    
        }    
    }    
    /**    
     * Method: Dump    
     *     Converts an AHK value into a JSON string    
     * Syntax:    
     *     str := JSON.Dump( value [, replacer, space ] )    
     * Parameter(s):    
     *     str        [retval] - JSON representation of an AHK value    
     *     value          [in] - any value(object, string, number)    
     *     replacer  [in, opt] - function object, similar to JavaScript's    
     *                           JSON.stringify() 'replacer' parameter    
     *     space     [in, opt] - similar to JavaScript's JSON.stringify()    
     *                           'space' parameter    
     */    
    class Dump extends JSON.Functor    
    {    
        Call(self, value, replacer:="", space:="")    
        {    
            this.rep := IsObject(replacer) ? replacer : ""    
            this.gap := ""    
            if (space) {    
                static integer := "integer"    
                if space is %integer%    
                    Loop, % ((n := Abs(space))>10 ? 10 : n)    
                        this.gap .= " "    
                else    
                    this.gap := SubStr(space, 1, 10)    
                this.indent := "`n"    
            }    
            return this.Str({"": value}, "")    
        }    
        Str(holder, key)    
        {    
            value := holder[key]    
            if (this.rep)    
                value := this.rep.Call(holder, key, ObjHasKey(holder, key) ? value : JSON.Undefined)    
            if IsObject(value) {    
            ; Check object type, skip serialization for other object types such as    
            ; ComObject, Func, BoundFunc, FileObject, RegExMatchObject, Property, etc.    
                static type := A_AhkVersion<"2" ? "" : Func("Type")    
                if (type ? type.Call(value) == "Object" : ObjGetCapacity(value) != "") {    
                    if (this.gap) {    
                        stepback := this.indent    
                        this.indent .= this.gap    
                    }    
                    is_array := value.IsArray    
                ; Array() is not overridden, rollback to old method of    
                ; identifying array-like objects. Due to the use of a for-loop    
                ; sparse arrays such as '[1,,3]' are detected as objects({}).     
                    if (!is_array) {    
                        for i in value    
                            is_array := i == A_Index    
                        until !is_array    
                    }    
                    str := ""    
                    if (is_array) {    
                        Loop, % value.Length() {    
                            if (this.gap)    
                                str .= this.indent    
                            v := this.Str(value, A_Index)    
                            str .= (v != "") ? v . "," : "null,"    
                        }    
                    } else {    
                        colon := this.gap ? ": " : ":"    
                        for k in value {    
                            v := this.Str(value, k)    
                            if (v != "") {    
                                if (this.gap)    
                                    str .= this.indent    
                                str .= this.Quote(k) . colon . v . ","    
                            }    
                        }    
                    }    
                    if (str != "") {    
                        str := RTrim(str, ",")    
                        if (this.gap)    
                            str .= stepback    
                    }    
                    if (this.gap)    
                        this.indent := stepback    
                    return is_array ? "[" . str . "]" : "{" . str . "}"    
                }    
            } else ; is_number ? value : "value"    
                return ObjGetCapacity([value], 1)=="" ? value : this.Quote(value)    
        }    
        Quote(string)    
        {    
            static quot := Chr(34), bashq := "\" . quot    
            if (string != "") {    
                string := StrReplace(string,  "\",  "\\")    
                ; , string := StrReplace(string,  "/",  "\/") ; optional in ECMAScript    
                , string := StrReplace(string, quot, bashq)    
                , string := StrReplace(string, "`b",  "\b")    
                , string := StrReplace(string, "`f",  "\f")    
                , string := StrReplace(string, "`n",  "\n")    
                , string := StrReplace(string, "`r",  "\r")    
                , string := StrReplace(string, "`t",  "\t")    
                static rx_escapable := A_AhkVersion<"2" ? "O)[^\x20-\x7e]" : "[^\x20-\x7e]"    
                while RegExMatch(string, rx_escapable, m)    
                    string := StrReplace(string, m.Value, Format("\u{1:04x}", Ord(m.Value)))    
            }    
            return quot . string . quot    
        }    
    }    
    /**    
     * Property: Undefined    
     *     Proxy for 'undefined' type    
     * Syntax:    
     *     undefined := JSON.Undefined    
     * Remarks:    
     *     For use with reviver and replacer functions since AutoHotkey does not    
     *     have an 'undefined' type. Returning blank("") or 0 won't work since these    
     *     can't be distnguished from actual JSON values. This leaves us with objects.    
     *     Replacer() - the caller may return a non-serializable AHK objects such as    
     *     ComObject, Func, BoundFunc, FileObject, RegExMatchObject, and Property to    
     *     mimic the behavior of returning 'undefined' in JavaScript but for the sake    
     *     of code readability and convenience, it's better to do 'return JSON.Undefined'.    
     *     Internally, the property returns a ComObject with the variant type of VT_EMPTY.    
     */    
    Undefined[]    
    {    
        get {    
            static empty := {}, vt_empty := ComObject(0, &empty, 1)    
            return vt_empty    
        }    
    }    
    class Functor    
    {    
        __Call(method, ByRef arg, args*)    
        {    
        ; When casting to Call(), use a new instance of the "function object"    
        ; so as to avoid directly storing the properties(used across sub-methods)    
        ; into the "function object" itself.    
            if IsObject(method)    
                return (new this).Call(method, arg, args*)    
            else if (method == "")    
                return (new this).Call(arg, args*)    
        }    
    }    
}

然后官方还有一段示例:

#Include %A_LineFile%\..\JSON.ahk    
json_str =    
(    
{    
    "str": "Hello World",    
    "num": 12345,    
    "float": 123.5,    
    "true": true,    
    "false": false,    
    "null": null,    
    "array": [    
        "Auto",    
        "Hot",    
        "key"    
    ],    
    "object": {    
        "A": "Auto",    
        "H": "Hot",    
        "K": "key"    
    }    
}    
)    
parsed := JSON.Load(json_str)    
parsed_out := Format("    
(Join`r`n    
String: {}    
Number: {}    
Float:  {}    
true:   {}    
false:  {}    
null:   {}    
array:  [{}, {}, {}]    
object: {{}A:""{}"", H:""{}"", K:""{}""{}}    
)"    
, parsed.str, parsed.num, parsed.float, parsed.true, parsed.false, parsed.null    
, parsed.array[1], parsed.array[2], parsed.array[3]    
, parsed.object.A, parsed.object.H, parsed.object.K)    
stringified := JSON.Dump(parsed,, 4)    
stringified := StrReplace(stringified, "`n", "`r`n") ; for display purposes only    
ListVars    
WinWaitActive ahk_class AutoHotkey    
ControlSetText Edit1, [PARSED]`r`n%parsed_out%`r`n`r`n[STRINGIFIED]`r`n%stringified%    
WinWaitClose    
return

服务器中了lpk.dll犇牛病毒

坑爹,不知道啥时候,服务器突然就中毒了,各种lpk.dll文件,exe全部被感染。还好我发现的不算太晚

前几天360已经预警我服务器网页挂了,我以为是因为长期开机,就重启了服务器。几天后又挂了。这才想到上下服务器看下情况。没想到任务管理器一打开,CPU100%,一直100%。内存也所剩无几。然后我也看到了奇怪的进程,数字.exe之类的进程有好几个。abcdefg文件详情的exe也好几个。这明显是中了木马或者病毒了。

果断的进入服务,禁用,进入任务管理器关闭所有奇怪的进程,360杀毒开启全盘。

截图.png

Total Commander 配置文件默认保存路径

最近重装了下系统,发现TC居然恢复了默认的配置,没有用我之前的配置。好奇之下,搜了下TC默认路径,百度出来都是说在C盘windows目录下,可是我找到的路径确实:C:\Users\用户名\AppData\Roaming\GHISLER。

看来百度出来的结果,信一半就好。(我之前有全盘备份了系统分区,所以这些文件都会存在。)

使用官方的Inireloc 软件把配置重新定位到我的TC安装目录下,然后把配置拷贝进来,重启下TC,成功。