暂未完工
This commit is contained in:
parent
7f3f49dc0d
commit
76ffd4a7cf
216
main.go
Normal file
216
main.go
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
Copyright Ghink Network Studio
|
||||||
|
Website: https://www.ghink.net
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"io"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
)
|
||||||
|
|
||||||
|
var WorkPath,DataPath string
|
||||||
|
var NodeList,Database,Dataread []map[string]string
|
||||||
|
var Loger *log.Logger
|
||||||
|
var ch chan bool
|
||||||
|
|
||||||
|
func responseICON(w http.ResponseWriter,r *http.Request) {
|
||||||
|
w.Header().Set("Location","https://resource.ghink.net/public/img/logo/ghink.png")
|
||||||
|
w.WriteHeader(301)
|
||||||
|
}
|
||||||
|
func responseError(w http.ResponseWriter,r *http.Request,httpCode int,info string,errorCode int) {
|
||||||
|
w.Header().Set("Content-Type","application/json")
|
||||||
|
w.WriteHeader(httpCode)
|
||||||
|
type returnError struct{
|
||||||
|
HttpCode int `json:"httpCode"`
|
||||||
|
Info string `json:"info"`
|
||||||
|
ErrorCode int `json:"errorCode"`
|
||||||
|
}
|
||||||
|
returnInfo:=returnError{httpCode,info,errorCode}
|
||||||
|
b,_:=json.Marshal(returnInfo)
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
func responseWiKi(w http.ResponseWriter,r *http.Request) {
|
||||||
|
w.Header().Set("Content-Type","application/json")
|
||||||
|
w.WriteHeader(200)
|
||||||
|
type returnWiki struct{
|
||||||
|
HttpCode int `json:"httpCode"`
|
||||||
|
Wiki string `json:"wiki"`
|
||||||
|
}
|
||||||
|
returnInfo:=returnWiki{200,"https://gitee.com/ghink/gmclapi/wikis"}
|
||||||
|
b,_:=json.Marshal(returnInfo)
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
func responseFile(w http.ResponseWriter,r *http.Request,value []string) {
|
||||||
|
path:=DataPath
|
||||||
|
for _,arg := range value{
|
||||||
|
path=path+"/"+arg
|
||||||
|
}
|
||||||
|
if path==""{
|
||||||
|
responseError(w,r,403,"Directory listing is not allowed",10002)
|
||||||
|
}else{
|
||||||
|
b,err:=ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
if find := strings.Contains(err.Error(),"The system cannot find"); find{
|
||||||
|
responseError(w,r,404,"Cannot find file",10003)
|
||||||
|
}else if s,_:=os.Stat(path); s.IsDir(){
|
||||||
|
responseError(w,r,403,"Directory listing is not allowed",10002)
|
||||||
|
}else{
|
||||||
|
responseError(w,r,500,"The file exists but cannot be read",10004)
|
||||||
|
logIn("[Page Thread]","Read the file ",path," failed in data dir! Error info: ",err.Error())
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func pageService(w http.ResponseWriter,r *http.Request) {
|
||||||
|
ts := time.Now().Unix()
|
||||||
|
logIn("[Page Thread]","Got requests from ",r.RemoteAddr,", address is ",r.URL.RequestURI())
|
||||||
|
w.Header().Set("Server","GMCLAPI (Alpha 1.0.0)")
|
||||||
|
w.Header().Set("Engine","Panda (Alpha 1.0.0)")
|
||||||
|
w.Header().Set("Stamp",fmt.Sprint(ts))
|
||||||
|
addr:=r.URL.RequestURI()
|
||||||
|
value:=strings.Split(addr,"/")
|
||||||
|
pathType:=value[1]
|
||||||
|
value=value[2:]
|
||||||
|
if addr=="/"{
|
||||||
|
responseWiKi(w,r)
|
||||||
|
}else{
|
||||||
|
switch pathType {
|
||||||
|
case "favicon.ico":
|
||||||
|
responseICON(w,r)
|
||||||
|
case "file":
|
||||||
|
responseFile(w,r,value)
|
||||||
|
/*
|
||||||
|
case "official":
|
||||||
|
responseOfficial(w,r,value)
|
||||||
|
case "bmclapi":
|
||||||
|
responseBMCLAPI(w,r,value)
|
||||||
|
case "default":
|
||||||
|
responseDefault(w,r,value)
|
||||||
|
case "gmclapi":
|
||||||
|
responseDefault(w,r,value)
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
responseError(w,r,405,"Unspported choice for requests loading",10001)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func databaseService() {
|
||||||
|
for {
|
||||||
|
file,err:=os.OpenFile(WorkPath+"/database.db",os.O_RDONLY,0600)
|
||||||
|
defer file.Close()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
bytes,err:=ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err=json.Unmarshal(bytes,&Database)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Duration(10)*time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func nodeService() {
|
||||||
|
|
||||||
|
}
|
||||||
|
func determineNode(file string) string {
|
||||||
|
return "http://127.0.0.1/file"+file
|
||||||
|
}
|
||||||
|
func syncService() {
|
||||||
|
for {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func hashFile(path string) string {
|
||||||
|
file,err:=os.Open(path)
|
||||||
|
defer file.Close()
|
||||||
|
if err != nil {
|
||||||
|
logIn("[Hash Thread]","Failed to calc hash of the file ",path,"! Error info: ",err.Error())
|
||||||
|
}
|
||||||
|
hash:=sha256.New()
|
||||||
|
if _,err := io.Copy(hash,file); err != nil {
|
||||||
|
logIn("[Hash Thread]","Failed to calc hash of the file ",path,"! Error info: ",err.Error())
|
||||||
|
}
|
||||||
|
sum:=hash.Sum(nil)
|
||||||
|
return hex.EncodeToString(sum)
|
||||||
|
}
|
||||||
|
func logIn(text ...string) {
|
||||||
|
result:=""
|
||||||
|
for _,arg := range text {
|
||||||
|
result+=arg
|
||||||
|
}
|
||||||
|
log.Print(result)
|
||||||
|
Loger.Print(result)
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
WorkPath="gmclapi/"
|
||||||
|
DataPath=WorkPath+"data/"
|
||||||
|
err:=os.MkdirAll(WorkPath, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err=os.MkdirAll(DataPath, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if _,err:=os.Stat(WorkPath+"database.db"); os.IsNotExist(err){
|
||||||
|
database,err:=os.OpenFile(WorkPath+"database.db", os.O_WRONLY|os.O_CREATE, 0666)
|
||||||
|
database.Write([]byte("[]"))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer database.Close()
|
||||||
|
}
|
||||||
|
file,err:=os.OpenFile(WorkPath+"/database.db", os.O_RDONLY,0600)
|
||||||
|
defer file.Close()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
bytes,err:=ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err=json.Unmarshal(bytes,&Database)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
logFile,err:=os.OpenFile(WorkPath+"logs.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer logFile.Close()
|
||||||
|
Loger=log.New(logFile,"",log.LstdFlags|log.Lshortfile)
|
||||||
|
http.HandleFunc("/", pageService)
|
||||||
|
go http.ListenAndServe("127.0.0.1:8000", nil)
|
||||||
|
go syncService()
|
||||||
|
go databaseService()
|
||||||
|
/*
|
||||||
|
go nodeService()
|
||||||
|
go consoleService()
|
||||||
|
*/
|
||||||
|
for {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
10001 Unspported choice for requests loading
|
||||||
|
10002 Directory listing is not allowed
|
||||||
|
10003 Cannot find file
|
||||||
|
10004 The file exists but cannot be read
|
||||||
|
*/
|
@ -1,8 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
//mainServer for GMCL API.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"log"
|
|
||||||
)
|
|
@ -1,8 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
//subDownloadServer for GMCL API.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"log"
|
|
||||||
)
|
|
@ -1,8 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
//subRequestServer for GMCL API.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"log"
|
|
||||||
)
|
|
97
sync.py
Normal file
97
sync.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
'''
|
||||||
|
Copyright Ghink Network Studio
|
||||||
|
Website: https://www.ghink.net
|
||||||
|
'''
|
||||||
|
import requests,os,time,json,threading,hashlib,re
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
db=[]
|
||||||
|
workPath="gmclapi/"
|
||||||
|
dataPath=workPath+"data/"
|
||||||
|
userAgent={'User-Agent':'GMCLAPI/0.0.1'}
|
||||||
|
proxies = {
|
||||||
|
"http": "http://127.0.0.1:4780"
|
||||||
|
}
|
||||||
|
entrance=["http://launchermeta.mojang.com/mc/game/version_manifest.json"]
|
||||||
|
|
||||||
|
def log(info):
|
||||||
|
info="{}{}".format(time.strftime("%Y/%m/%d %H:%M:%S [Sync Thread]", time.localtime()),info)
|
||||||
|
print(info)
|
||||||
|
with open(workPath+"logs.log","a+") as fb:
|
||||||
|
fb.write(info)
|
||||||
|
fb.write("\r\n")
|
||||||
|
def database():
|
||||||
|
global db
|
||||||
|
with open(workPath+"database.db","r") as fb:
|
||||||
|
db=json.loads(fb.read())
|
||||||
|
while True:
|
||||||
|
with open(workPath+"database.db","r") as fb:
|
||||||
|
if json.loads(fb.read())==db:
|
||||||
|
continue
|
||||||
|
with open(workPath+"database.db","w+") as fb:
|
||||||
|
fb.write(json.dumps(db))
|
||||||
|
def syncMain():
|
||||||
|
global entrance
|
||||||
|
global userAgent
|
||||||
|
global proxies
|
||||||
|
for obj in entrance:
|
||||||
|
origin=requests.get(obj,headers=userAgent,proxies=proxies).content
|
||||||
|
md5=hashlib.md5()
|
||||||
|
md5.update(origin)
|
||||||
|
hash=md5.hexdigest()
|
||||||
|
switch=True
|
||||||
|
for h in db:
|
||||||
|
if h["hash"]==hash:
|
||||||
|
switch=False
|
||||||
|
break
|
||||||
|
if switch:
|
||||||
|
i=0
|
||||||
|
for h in db:
|
||||||
|
if h["path"]==urlparse(obj).path:
|
||||||
|
del switch[i]
|
||||||
|
i+=1
|
||||||
|
with open(dataPath+hash,"wb") as fb:
|
||||||
|
fb.write(origin)
|
||||||
|
db.append({
|
||||||
|
"hash":hash,
|
||||||
|
"source":obj,
|
||||||
|
"path":urlparse(obj).path
|
||||||
|
})
|
||||||
|
def syncMinecraft():
|
||||||
|
global userAgent
|
||||||
|
global proxies
|
||||||
|
for h in db:
|
||||||
|
if h["path"]=="/mc/game/version_manifest.json":
|
||||||
|
hash=h["hash"]
|
||||||
|
break
|
||||||
|
with open(dataPath+hash,"r") as fb:
|
||||||
|
fall=fb.read()
|
||||||
|
result=re.findall('(https?|ftp|file)|([-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])',fall)
|
||||||
|
print(result)
|
||||||
|
res=[]
|
||||||
|
for i in result:
|
||||||
|
res.append("{}{}".format(i[0]+i[1]))
|
||||||
|
for obj in res:
|
||||||
|
switch=True
|
||||||
|
for h in db:
|
||||||
|
if h["source"]==obj:
|
||||||
|
switch=False
|
||||||
|
if switch:
|
||||||
|
origin=requests.get(obj,headers=userAgent,proxies=proxies).content
|
||||||
|
md5=hashlib.md5()
|
||||||
|
md5.update(origin)
|
||||||
|
hash=md5.hexdigest()
|
||||||
|
with open(dataPath+hash,"wb") as fb:
|
||||||
|
fb.write(origin)
|
||||||
|
db.append({
|
||||||
|
"hash":hash,
|
||||||
|
"source":obj,
|
||||||
|
"path":urlparse(obj).path
|
||||||
|
})
|
||||||
|
def main():
|
||||||
|
threading.Thread(target=database).start()
|
||||||
|
syncMain()
|
||||||
|
#main()
|
||||||
|
threading.Thread(target=database).start()
|
||||||
|
time.sleep(1)
|
||||||
|
syncMinecraft()
|
Reference in New Issue
Block a user