Compare commits
No commits in common. "7f7d10aeee55d0af1b33408880440873dcd9425e" and "18828ca7207fbd11662b40ca5a9759ea6cdf348a" have entirely different histories.
7f7d10aeee
...
18828ca720
19 changed files with 10324 additions and 257 deletions
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
format() {
|
|
||||||
sed -e 's/^fix:/доза:/' \
|
|
||||||
-e '/^# ------------------------ >8 ------------------------$/,$d' \
|
|
||||||
-e '/^#/d'
|
|
||||||
}
|
|
||||||
|
|
||||||
translated="$(curl -s \
|
|
||||||
http://localhost:9000/translate \
|
|
||||||
-H 'Content-Type: text/html' \
|
|
||||||
--data-binary @- -o- < <(format < "$1") | \
|
|
||||||
tail -n +2 | \
|
|
||||||
perl -pe 's,<SPAN CLASS=UNKNOWN_WORD>(.*?)</SPAN>,\1,g')"
|
|
||||||
|
|
||||||
[ -n "$translated" ] && echo "$translated" > "$1"
|
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1,4 +1,6 @@
|
||||||
build/
|
|
||||||
.cache/
|
.cache/
|
||||||
|
/test
|
||||||
|
build/
|
||||||
|
cache/
|
||||||
cmake-build*/
|
cmake-build*/
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
|
|
||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
[submodule "puppy/include/http"]
|
|
||||||
path = puppy/include/http
|
|
||||||
url = https://github.com/yhirose/cpp-httplib
|
|
||||||
34
README.md
34
README.md
|
|
@ -1,34 +0,0 @@
|
||||||
# promty
|
|
||||||
|
|
||||||
## Собирание
|
|
||||||
|
|
||||||
Чтобы строить проект, Вы нуждаетесь:
|
|
||||||
1. Получить **законную копию** "X-переводчика ПРОМТ Magic Gooddy 6.0.0.205" (да, мы фактически имеем эти DVD),
|
|
||||||
2. Установите это на вашей машине "Окна"
|
|
||||||
3. Бегите сервером SSH на той машине
|
|
||||||
4. Управляемый `puppy/scripts/prepare_environment.sh "WINDOWS_USER@WINDOWS_IP"`. Это будет тянуть все необходимые файлы и ключи регистр
|
|
||||||
5. Управляемый `docker compose up -d --build`
|
|
||||||
|
|
||||||
## Вклад
|
|
||||||
|
|
||||||
### Передайте Стиль
|
|
||||||
|
|
||||||
Эти использования проекта, для которых "обычное передает формат", передают сообщения.
|
|
||||||
|
|
||||||
```
|
|
||||||
напечатайте [возможности]: передайте описание
|
|
||||||
|
|
||||||
дополнительное тело
|
|
||||||
|
|
||||||
дополнительная нижняя
|
|
||||||
```
|
|
||||||
|
|
||||||
Мы используем только известный, стандартизированный передают типы как определено спецификацией:
|
|
||||||
|
|
||||||
| Напечатать | Описание |
|
|
||||||
|------------------------|-----------------------------------------------------------------------------------------------------------|
|
|
||||||
| `подвиг` | Добавляет, что новая особенность к codebase |
|
|
||||||
| `доза` | Залатать неполадки в codebase |
|
|
||||||
| `доктора` | Изменения только для докторов |
|
|
||||||
| `тест` | Сменить испытания |
|
|
||||||
| `хозяйственная работа` | Изменения, которые непосредственно не затрагивают кодекс, типа ударов версии или обновлений иждивенчества |
|
|
||||||
|
|
@ -14,10 +14,6 @@ http://ядро.орг, http://*.ядро.орг {
|
||||||
# we don't want to flood the upstream from the same IP
|
# we don't want to flood the upstream from the same IP
|
||||||
mode bypass
|
mode bypass
|
||||||
ttl 30m
|
ttl 30m
|
||||||
|
|
||||||
timeout {
|
|
||||||
backend 10m
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
import Caddyfile.yadro proxy:80
|
import Caddyfile.yadro proxy:80
|
||||||
|
|
@ -27,24 +23,13 @@ http://ядро.орг, http://*.ядро.орг {
|
||||||
reverse_proxy {
|
reverse_proxy {
|
||||||
dynamic a puppy 80
|
dynamic a puppy 80
|
||||||
lb_policy least_conn
|
lb_policy least_conn
|
||||||
|
|
||||||
transport http {
|
|
||||||
response_header_timeout 10m
|
|
||||||
read_timeout 10m
|
|
||||||
write_timeout 10m
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cache {
|
cache {
|
||||||
allowed_http_verbs POST
|
allowed_http_verbs POST
|
||||||
ttl 7d
|
ttl 7d
|
||||||
|
|
||||||
key {
|
|
||||||
headers X-Translation-Direction
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout {
|
timeout {
|
||||||
backend 10m
|
backend 1m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,6 @@ handle @surely_static {
|
||||||
redir @known_host https://{kernel}{uri} permanent
|
redir @known_host https://{kernel}{uri} permanent
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO: cache by path for 30 minutes
|
# TOOO: cache by path for 30 minutes
|
||||||
|
|
||||||
reverse_proxy {args[0]}
|
reverse_proxy {args[0]}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
FROM caddy:builder AS builder
|
FROM caddy:builder AS builder
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/go/pkg/mod xcaddy build \
|
RUN --mount=type=cache,target=/go/pkg/mod xcaddy build \
|
||||||
--with github.com/caddyserver/cache-handler
|
--with github.com/caddyserver/cache-handler
|
||||||
|
|
||||||
FROM caddy:latest
|
FROM caddy:latest
|
||||||
|
|
||||||
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,33 @@
|
||||||
services:
|
services:
|
||||||
puppies:
|
puppies:
|
||||||
networks: [promty]
|
networks:
|
||||||
|
- promty
|
||||||
build: puppy
|
build: puppy
|
||||||
hostname: puppy
|
hostname: puppy
|
||||||
|
stop_signal: SIGINT
|
||||||
volumes:
|
volumes:
|
||||||
- /dev/shm/puppy-temp:/tmpfs
|
- /dev/shm/puppy-temp:/tmpfs
|
||||||
|
- ./cache:/cache
|
||||||
deploy:
|
deploy:
|
||||||
mode: replicated
|
mode: replicated
|
||||||
replicas: 3
|
replicas: 1
|
||||||
endpoint_mode: vip
|
endpoint_mode: vip
|
||||||
update_config:
|
|
||||||
order: start-first
|
|
||||||
|
|
||||||
proxy:
|
proxy:
|
||||||
networks: [promty]
|
networks:
|
||||||
|
- promty
|
||||||
container_name: proxy
|
container_name: proxy
|
||||||
build: proxy
|
build: proxy
|
||||||
depends_on:
|
|
||||||
puppies:
|
|
||||||
condition: service_healthy
|
|
||||||
|
|
||||||
caddy:
|
caddy:
|
||||||
networks: [promty]
|
networks:
|
||||||
|
- promty
|
||||||
container_name: caddy
|
container_name: caddy
|
||||||
build: caddy
|
build: caddy
|
||||||
volumes:
|
volumes:
|
||||||
- ./caddy:/etc/caddy
|
- ./caddy:/etc/caddy
|
||||||
depends_on: [proxy]
|
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
- 9000:9000
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
promty:
|
promty:
|
||||||
|
|
|
||||||
10
domains
10
domains
|
|
@ -25,7 +25,7 @@
|
||||||
линукс.ядро.орг linux.kernel.org
|
линукс.ядро.орг linux.kernel.org
|
||||||
саял.ядро.орг lkml.kernel.org
|
саял.ядро.орг lkml.kernel.org
|
||||||
уздечка.ядро.орг lore.kernel.org
|
уздечка.ядро.орг lore.kernel.org
|
||||||
кольчуга.ядро.орг mail.kernel.org
|
почта.ядро.орг mail.kernel.org
|
||||||
социальные.сми.ядро.орг media.social.kernel.org
|
социальные.сми.ядро.орг media.social.kernel.org
|
||||||
край.зеркал.ядро.орг mirrors.edge.kernel.org
|
край.зеркал.ядро.орг mirrors.edge.kernel.org
|
||||||
зеркала.ядро.орг mirrors.kernel.org
|
зеркала.ядро.орг mirrors.kernel.org
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
уздечка.сппн.ядро.орг nntp.lore.kernel.org
|
уздечка.сппн.ядро.орг nntp.lore.kernel.org
|
||||||
нью-йоркские.зеркала.ядро.орг ny.mirrors.kernel.org
|
нью-йоркские.зеркала.ядро.орг ny.mirrors.kernel.org
|
||||||
источник.нук.ядро.орг nyc.source.kernel.org
|
источник.нук.ядро.орг nyc.source.kernel.org
|
||||||
прокладка.ядро.орг pad.kernel.org
|
клавиатура.ядро.орг pad.kernel.org
|
||||||
доктора.париж.ядро.орг parisc.docs.kernel.org
|
доктора.париж.ядро.орг parisc.docs.kernel.org
|
||||||
путаница.ядро.орг patchwork.kernel.org
|
путаница.ядро.орг patchwork.kernel.org
|
||||||
люди.ядро.орг people.kernel.org
|
люди.ядро.орг people.kernel.org
|
||||||
|
|
@ -43,13 +43,13 @@
|
||||||
источник.греха.ядро.орг sin.source.kernel.org
|
источник.греха.ядро.орг sin.source.kernel.org
|
||||||
пппп.ядро.орг smtp.kernel.org
|
пппп.ядро.орг smtp.kernel.org
|
||||||
уздечка.пппп.ядро.орг smtp.lore.kernel.org
|
уздечка.пппп.ядро.орг smtp.lore.kernel.org
|
||||||
подпространство.пппп.ядро.орг smtp.subspace.kernel.org
|
подместо.пппп.ядро.орг smtp.subspace.kernel.org
|
||||||
пппп1.ядро.орг smtp1.kernel.org
|
пппп1.ядро.орг smtp1.kernel.org
|
||||||
пппп2.ядро.орг smtp2.kernel.org
|
пппп2.ядро.орг smtp2.kernel.org
|
||||||
пппп3.ядро.орг smtp3.kernel.org
|
пппп3.ядро.орг smtp3.kernel.org
|
||||||
социальное.ядро.орг social.kernel.org
|
социальный.ядро.орг social.kernel.org
|
||||||
редкие.доктора.ядро.орг sparse.docs.kernel.org
|
редкие.доктора.ядро.орг sparse.docs.kernel.org
|
||||||
подпространство.ядро.орг subspace.kernel.org
|
подместо.ядро.орг subspace.kernel.org
|
||||||
зеркала.резюме.ядро.орг sv.mirrors.kernel.org
|
зеркала.резюме.ядро.орг sv.mirrors.kernel.org
|
||||||
сай.отражает.ядро.орг sy.mirrors.kernel.org
|
сай.отражает.ядро.орг sy.mirrors.kernel.org
|
||||||
мпук.ядро.орг vger.kernel.org
|
мпук.ядро.орг vger.kernel.org
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
FROM golang:1.23-alpine AS builder
|
FROM golang:1.23-alpine AS builder
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
COPY . .
|
COPY . .
|
||||||
|
RUN --mount=type=cache,target=/go/pkg/mod go build
|
||||||
RUN --mount=type=cache,target=/go/pkg/mod go build;
|
|
||||||
|
|
||||||
|
|
||||||
FROM alpine AS runner
|
FROM alpine AS runner
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /build/proxy .
|
COPY --from=builder /build/proxy .
|
||||||
|
|
||||||
EXPOSE 80/tcp
|
EXPOSE 80/tcp
|
||||||
CMD ./proxy
|
CMD ./proxy
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ func main() {
|
||||||
|
|
||||||
// We only support gzip decoding
|
// We only support gzip decoding
|
||||||
r.Out.Header.Set("Accept-Encoding", "gzip")
|
r.Out.Header.Set("Accept-Encoding", "gzip")
|
||||||
r.Out.Header.Set("User-Agent", "ядро.орг/1.0")
|
|
||||||
},
|
},
|
||||||
ModifyResponse: func(r *http.Response) error {
|
ModifyResponse: func(r *http.Response) error {
|
||||||
// Disable security policy because of the domain restrictions.
|
// Disable security policy because of the domain restrictions.
|
||||||
|
|
@ -68,7 +67,7 @@ func main() {
|
||||||
return original_raw
|
return original_raw
|
||||||
}
|
}
|
||||||
|
|
||||||
return []byte("https://" + yadro + "/")
|
return []byte("http://" + yadro + "/") // TODO: https
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,15 +87,11 @@ func main() {
|
||||||
http.ListenAndServe("0.0.0.0:80", proxy)
|
http.ListenAndServe("0.0.0.0:80", proxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func replaceDomains(response string) string {
|
func replaceDomains(response []byte) []byte {
|
||||||
re := regexp.MustCompile(`(?i)[A-Za-z\-\.]*\.?kernel\.org`)
|
re := regexp.MustCompile(`(?i)[A-Za-z\-\.]*\.?kernel\.org`)
|
||||||
response = strings.NewReplacer(
|
|
||||||
"%3F", "?",
|
|
||||||
"%26", "&",
|
|
||||||
).Replace(response)
|
|
||||||
|
|
||||||
response = re.ReplaceAllStringFunc(response, func(original_raw string) string {
|
response = re.ReplaceAllFunc(response, func(original_raw []byte) []byte {
|
||||||
kernel := strings.ToLower(original_raw)
|
kernel := strings.ToLower(string(original_raw))
|
||||||
|
|
||||||
// Strip `www.`
|
// Strip `www.`
|
||||||
kernel = strings.TrimPrefix(kernel, "www.")
|
kernel = strings.TrimPrefix(kernel, "www.")
|
||||||
|
|
@ -108,46 +103,42 @@ func replaceDomains(response string) string {
|
||||||
return original_raw
|
return original_raw
|
||||||
}
|
}
|
||||||
|
|
||||||
return yadro
|
return []byte(yadro)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
response = bytes.ReplaceAll(response, []byte("%3F"), []byte("?"))
|
||||||
|
response = bytes.ReplaceAll(response, []byte("%26"), []byte("&"))
|
||||||
|
response = bytes.ReplaceAll(response, []byte("https"), []byte("http")) // TODO: TEMP
|
||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
func translateWithPromtPuppies(response string) string {
|
func translateWithPromtPuppies(response []byte) []byte {
|
||||||
// Don't try to translate empty body (30x, etc)
|
// Don't try to translate empty body (30x, etc)
|
||||||
if len(response) == 0 {
|
if len(response) == 0 {
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
req, _ := http.NewRequest("POST", "http://caddy:9000/translate", strings.NewReader(response))
|
req, _ := http.NewRequest("POST", "http://caddy:9000/translate", bytes.NewReader(response))
|
||||||
|
|
||||||
req.Header.Add("Content-Type", "text/html")
|
req.Header.Add("Content-Type", "text/html")
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "Error in while translating", err)
|
fmt.Fprintln(os.Stderr, "Error in first", err)
|
||||||
return ""
|
return []byte{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
var translated strings.Builder
|
response, _ = io.ReadAll(resp.Body)
|
||||||
io.Copy(&translated, resp.Body)
|
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
|
|
||||||
return translated.String()
|
return response
|
||||||
}
|
|
||||||
|
|
||||||
func enfunnify(response string) string {
|
|
||||||
return strings.NewReplacer(
|
|
||||||
"tarball", "tar ball",
|
|
||||||
).Replace(response)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func modifyResponse(response []byte) []byte {
|
func modifyResponse(response []byte) []byte {
|
||||||
s := string(response)
|
response = translateWithPromtPuppies(response)
|
||||||
s = enfunnify(s)
|
response = replaceDomains(response)
|
||||||
s = translateWithPromtPuppies(s)
|
return response
|
||||||
s = replaceDomains(s)
|
|
||||||
return []byte(s)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,41 @@
|
||||||
#check=skip=JSONArgsRecommended
|
#check=skip=JSONArgsRecommended
|
||||||
|
FROM debian:12-slim AS builder
|
||||||
FROM debian:13-slim AS builder
|
|
||||||
RUN apt-get update && DEBIAN_FRONTEND=noninteracive apt-get install -y \
|
RUN apt-get update && DEBIAN_FRONTEND=noninteracive apt-get install -y \
|
||||||
--no-install-recommends cmake g++-mingw-w64-i686-posix g++ make && \
|
--no-install-recommends cmake g++-mingw-w64-i686-posix g++ make && \
|
||||||
apt-get clean && rm -rf /var/lib/apt/lists/*;
|
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
COPY . .
|
||||||
COPY app/healthcheck.cpp app/healthcheck.cpp
|
RUN g++ -o healthcheck -I./include ./app/healthcheck.cpp
|
||||||
COPY include/http include/http
|
|
||||||
RUN g++ -o healthcheck -I./include ./app/healthcheck.cpp;
|
|
||||||
|
|
||||||
COPY app app
|
|
||||||
COPY include include
|
|
||||||
COPY src src
|
|
||||||
COPY CMakeLists.txt .
|
|
||||||
|
|
||||||
RUN --mount=type=cache,target=cmake-build cmake -B cmake-build \
|
RUN --mount=type=cache,target=cmake-build cmake -B cmake-build \
|
||||||
-DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++ && cmake --build cmake-build -j$(nproc) && \
|
-DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++ && cmake --build cmake-build -j$(nproc) && \
|
||||||
cp cmake-build/promt-puppy.exe .;
|
cp cmake-build/promt-puppy.exe .
|
||||||
|
|
||||||
|
FROM debian:12-slim AS runner
|
||||||
FROM debian:13-slim AS runner
|
|
||||||
ENV WINEPREFIX=/wineprefix \
|
ENV WINEPREFIX=/wineprefix \
|
||||||
XDG_RUNTIME_DIR=/tmp/ \
|
DEBIAN_FRONTEND=noninteracive
|
||||||
DEBIAN_FRONTEND=noninteracive \
|
|
||||||
WINEDEBUG=-all
|
|
||||||
|
|
||||||
RUN dpkg --add-architecture i386 && apt-get update && \
|
RUN dpkg --add-architecture i386 && apt-get update && \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
wine wine64 wine32:i386 && \
|
wine wine64 wine32:i386 && \
|
||||||
apt-get clean && rm -rf /var/lib/apt/lists/* && \
|
apt-get clean && rm -rf /var/lib/apt/lists/* && \
|
||||||
mkdir -p /tmpfs $WINEPREFIX/drive_c && ln -sf /tmpfs $WINEPREFIX/drive_c/tmpfs;
|
wineboot -i && echo "Sleeping for 15 seconds..." && sleep 15 && \
|
||||||
|
mkdir /tmpfs && ln -sf /tmpfs $WINEPREFIX/drive_c/tmpfs
|
||||||
|
|
||||||
|
|
||||||
COPY build/ $WINEPREFIX/drive_c
|
COPY build/ $WINEPREFIX/drive_c
|
||||||
|
RUN wine regedit $WINEPREFIX/drive_c/registry.reg && \
|
||||||
|
echo "Sleeping for 15 seconds" && sleep 15
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=builder /build/promt-puppy.exe /build/healthcheck .
|
COPY --from=builder /build/promt-puppy.exe /build/healthcheck .
|
||||||
HEALTHCHECK --start-period=30s --start-interval=1s CMD ./healthcheck;
|
|
||||||
|
HEALTHCHECK CMD ./healthcheck
|
||||||
|
|
||||||
EXPOSE 80/tcp
|
EXPOSE 80/tcp
|
||||||
VOLUME /cache
|
VOLUME /cache
|
||||||
STOPSIGNAL SIGINT
|
|
||||||
|
|
||||||
COPY docker-entrypoint.sh /entrypoint.sh
|
ENV WINEDEBUG=-all
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
|
||||||
|
CMD exec wine promt-puppy.exe
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include "http/httplib.h"
|
#include "httplib.hpp"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
auto res = httplib::Client("127.0.0.1", 80).Get("/health");
|
auto res = httplib::Client("127.0.0.1", 80).Get("/health");
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,18 @@
|
||||||
#include "http/httplib.h"
|
#include "httplib.hpp"
|
||||||
|
|
||||||
#include <csignal>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <functional>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <windows.h>
|
|
||||||
#include <winternl.h>
|
|
||||||
|
|
||||||
#include "PromtCtlDocument.hpp"
|
#include "PromtCtlDocument.hpp"
|
||||||
#include "PromtFTManager.hpp"
|
#include "PromtFTManager.hpp"
|
||||||
|
|
||||||
#define EPOCH_DIFF 116444736000000000LL
|
|
||||||
#define TICKS_PER_SEC 10000000LL
|
|
||||||
|
|
||||||
static LARGE_INTEGER fake_time;
|
|
||||||
|
|
||||||
static NTSTATUS WINAPI HookedNtQuerySystemTime(PLARGE_INTEGER time)
|
|
||||||
{
|
|
||||||
if (time)
|
|
||||||
time->QuadPart = fake_time.QuadPart;
|
|
||||||
|
|
||||||
fake_time.QuadPart += TICKS_PER_SEC;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void InstallTimeHook()
|
|
||||||
{
|
|
||||||
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
|
|
||||||
if (!ntdll)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto target = (BYTE *)GetProcAddress(ntdll, "NtQuerySystemTime");
|
|
||||||
if (!target)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DWORD old;
|
|
||||||
VirtualProtect(target, 5, PAGE_EXECUTE_READWRITE, &old);
|
|
||||||
|
|
||||||
intptr_t rel = (BYTE *)HookedNtQuerySystemTime - target - 5;
|
|
||||||
target[0] = 0xE9; // jmp rel32
|
|
||||||
*(int32_t *)(target + 1) = (int32_t)rel;
|
|
||||||
|
|
||||||
VirtualProtect(target, 5, old, &old);
|
|
||||||
|
|
||||||
const char *env = std::getenv("FAKETIME");
|
|
||||||
long long unix_ts = env ? std::strtoll(env, nullptr, 10) : 0;
|
|
||||||
fake_time.QuadPart = unix_ts * TICKS_PER_SEC + EPOCH_DIFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline std::string random_filename(int len = 65) {
|
static inline std::string random_filename(int len = 65) {
|
||||||
static const char ASCII_PRINTABLE[] = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
static const char ASCII_PRINTABLE[] = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
static std::random_device random_device;
|
std::random_device random_device;
|
||||||
static std::mt19937 generator(random_device());
|
std::mt19937 generator(random_device());
|
||||||
static std::uniform_int_distribution distribution(0, static_cast<int>(strlen(ASCII_PRINTABLE) - 1));
|
std::uniform_int_distribution distribution(0, static_cast<int>(strlen(ASCII_PRINTABLE) - 1));
|
||||||
std::string random_string;
|
std::string random_string;
|
||||||
random_string.reserve(len);
|
random_string.reserve(len);
|
||||||
for (int i = 0; i < len; ++i)
|
for (int i = 0; i < len; ++i)
|
||||||
|
|
@ -105,20 +61,11 @@ static inline auto read_file(const std::string &filename) {
|
||||||
|
|
||||||
size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, 0, 0);
|
size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, 0, 0);
|
||||||
std::string out;
|
std::string out;
|
||||||
out.resize(size - 1);
|
out.resize(size);
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, out.data(), size - 1, 0, 0);
|
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, out.data(), size, 0, 0);
|
||||||
delete[] wstr;
|
delete[] wstr;
|
||||||
|
|
||||||
std::string out_lf;
|
return out;
|
||||||
out_lf.reserve(out.size());
|
|
||||||
|
|
||||||
for (auto c : out) {
|
|
||||||
if (c == '\r')
|
|
||||||
continue;
|
|
||||||
out_lf.push_back(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
return out_lf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class WebServer {
|
class WebServer {
|
||||||
|
|
@ -195,8 +142,7 @@ class WebServer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WebServer() {
|
WebServer() {
|
||||||
if (!std::filesystem::exists(TMP_FOLDER))
|
if (!std::filesystem::exists(TMP_FOLDER)) std::filesystem::create_directory(TMP_FOLDER);
|
||||||
std::filesystem::create_directory(TMP_FOLDER);
|
|
||||||
|
|
||||||
m_svr.Post("/translate", [this](const httplib::Request &req, httplib::Response &res) {
|
m_svr.Post("/translate", [this](const httplib::Request &req, httplib::Response &res) {
|
||||||
TranslateHandler(req, res);
|
TranslateHandler(req, res);
|
||||||
|
|
@ -213,7 +159,6 @@ class WebServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
void listen(const char *host = "0.0.0.0", unsigned short port = 80) {
|
void listen(const char *host = "0.0.0.0", unsigned short port = 80) {
|
||||||
print("started!");
|
|
||||||
m_svr.listen(host, port);
|
m_svr.listen(host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,23 +169,12 @@ class WebServer {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::function<void(int)> signal_action;
|
|
||||||
|
|
||||||
void signal_handler(int signal) {
|
|
||||||
signal_action(signal);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
InstallTimeHook();
|
print("Starting...");
|
||||||
|
|
||||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||||
CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, nullptr, EOAC_NONE, nullptr);
|
CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, nullptr, EOAC_NONE, nullptr);
|
||||||
|
|
||||||
WebServer ws;
|
WebServer ws;
|
||||||
|
|
||||||
signal_action = [&](int x) { ws.stop(); };
|
|
||||||
std::signal(SIGTERM, signal_handler);
|
|
||||||
std::signal(SIGINT, signal_handler);
|
|
||||||
|
|
||||||
ws.listen();
|
ws.listen();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# shellcheck disable=SC2155
|
|
||||||
|
|
||||||
echo 'initializing wine...'
|
|
||||||
wineboot -i
|
|
||||||
|
|
||||||
echo 'copying registy values...'
|
|
||||||
wine regedit "$WINEPREFIX"/drive_c/registry.reg
|
|
||||||
|
|
||||||
export FAKETIME="$(cat "$WINEPREFIX"/drive_c/build-date)"
|
|
||||||
echo "starting with date $(date -d @"$FAKETIME")..."
|
|
||||||
exec wine /app/promt-puppy.exe
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit adf58bf474fac638160592d6c3f67da4ebc7df20
|
|
||||||
10243
puppy/include/httplib.hpp
Normal file
10243
puppy/include/httplib.hpp
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,25 +1,15 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
# shellcheck disable=SC1091
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(dirname "$(dirname "$(readlink -e "$0")")")"
|
cd "$(basename "$(basename "$(readlink "$0")")")"
|
||||||
|
|
||||||
SSH_HOST="${1:?Missing SSH host}"
|
SSH_HOST="${1:?Missing SSH host}"
|
||||||
|
|
||||||
mkdir -p build/{"Program Files (x86)/Common Files",ProgramData}
|
mkdir -p build/{"Program Files (x86)/Common Files",ProgramData}
|
||||||
scp "$SCRIPT_DIR/scripts/dump_registry.ps1" "$SSH_HOST:"
|
# scp ./scripts/dump_registry.ps1 "$SSH_HOST:"
|
||||||
ssh "$SSH_HOST" "powershell .\dump_registry.ps1"
|
# ssh "$SSH_HOST" "powershell .\dump_registry.ps1"
|
||||||
scp "$SSH_HOST:promt-registry.reg" build/registry.reg
|
scp "$SSH_HOST:promt-registry.reg" build/registry.reg
|
||||||
ssh "$SSH_HOST" powershell -c 'rm promt-registry.reg'
|
ssh "$SSH_HOST" powershell -c 'rm promt-registry.reg'
|
||||||
|
|
||||||
scp -r "$SSH_HOST:/Program Files (x86)/Common Files/PROject MT" "$SCRIPT_DIR/build/Program Files (x86)/Common Files/PROject MT"
|
scp -r "$SSH_HOST:/Program Files (x86)/Common Files/PROject MT" "./build/Program Files (x86)/Common Files/PROject MT"
|
||||||
scp -r "$SSH_HOST:/Program Files (x86)/PRMT6" "$SCRIPT_DIR/build/Program Files (x86)/PRMT6"
|
scp -r "$SSH_HOST:/Program Files (x86)/PRMT6" "./build/Program Files (x86)/PRMT6"
|
||||||
scp -r "$SSH_HOST:/ProgramData/PROject MT" "$SCRIPT_DIR/build/ProgramData/PROject MT"
|
scp -r "$SSH_HOST:/ProgramData/PROject MT" "./build/ProgramData/PROject MT"
|
||||||
|
|
||||||
export WINETRICKS_LIB=1
|
|
||||||
. winetricks 2>/dev/null
|
|
||||||
|
|
||||||
winetricks_init
|
|
||||||
winetricks_vcrun6_helper
|
|
||||||
w_try_cabextract "${W_CACHE}"/vcrun6/vcredist.exe -d "$SCRIPT_DIR/build/windows/" -F "mfc42*.dll"
|
|
||||||
mkdir -p "$SCRIPT_DIR/build/windows/system32"
|
|
||||||
|
|
||||||
date +'%s' > "$SCRIPT_DIR/build/build-date"
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
#include "COMWrapper.hpp"
|
#include "COMWrapper.hpp"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <stdexcept>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <comdef.h>
|
|
||||||
|
|
||||||
void COMWrapper::Raise(const HRESULT hr, const char *const ctx) const {
|
void COMWrapper::Raise(const HRESULT hr, const char *const ctx) const {
|
||||||
if (hr != 0) {
|
if (hr != 0) {
|
||||||
char msg[1024];
|
char msg[128];
|
||||||
_com_error err(hr);
|
snprintf(msg, 128, "[%s] Non-zero HRESULT value: 0x%x at: %s\n", classname(), hr, ctx);
|
||||||
snprintf(msg, 1024, "[%s] Error: %s (0x%lx) at: %s\n", classname(), err.ErrorMessage(), hr, ctx);
|
printf(msg);
|
||||||
printf("%s\n", msg);
|
throw std::runtime_error(msg);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue