commit 3039c28cb807cff5c36e3e0338af5707ce20efdf
parent dd12a7e9842449622227e8f70ee07ba1b3157937
Author: sin <sin@2f30.org>
Date: Thu, 20 Jun 2013 16:23:30 +0100
Add d2-resurrect.c and get.go
Diffstat:
A | d2-resurrect.c | | | 127 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | get.go | | | 54 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 181 insertions(+), 0 deletions(-)
diff --git a/d2-resurrect.c b/d2-resurrect.c
@@ -0,0 +1,127 @@
+/* Resurrect hardcore characters in Diablo 2 */
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <err.h>
+
+static uint32_t
+rotl(const uint32_t value, int shift)
+{
+ if ((shift &= sizeof(value) * 8 - 1) == 0)
+ return value;
+ return (value << shift) | (value >> (sizeof(value) * 8 - shift));
+}
+
+static void
+usage(const char *prog)
+{
+ fprintf(stderr, "usage: %s [-h] <d2s>\n", prog);
+ fprintf(stderr, " -h\tMake player hardcore\n");
+}
+
+static int hflag;
+
+int
+main(int argc, char *argv[])
+{
+ struct stat sbuf;
+ const char *prog;
+ unsigned char *buf;
+ unsigned char tmp;
+ int ret, fd, i, c;
+ uint32_t chksum;
+ uint32_t status;
+
+ prog = *argv;
+
+ for (c = 0; c >= 0; c = getopt(argc, argv, "h")) {
+ switch (c) {
+ case 'h':
+ hflag = true;
+ break;
+ case '?':
+ usage(prog);
+ return 1;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ usage(prog);
+ return 1;
+ }
+
+ fd = open(*argv, O_RDWR);
+ if (fd < 0)
+ err(1, "open");
+
+ ret = fstat(fd, &sbuf);
+ if (ret < 0)
+ err(1, "fstat");
+
+ buf = malloc(sbuf.st_size);
+ if (!buf)
+ err(1, "malloc");
+
+ ret = read(fd, buf, sbuf.st_size);
+ if (ret != sbuf.st_size)
+ err(1, "read");
+
+ status = buf[0x24];
+ printf("old character status: %#hhx, bitmap: [", status);
+ for (i = 7; i >= 0; i--) {
+ if (status & (1 << i))
+ putchar('1');
+ else
+ putchar('0');
+ }
+ printf("]\n");
+ if (status & (1 << 3)) {
+ printf("resurrecting character...\n");
+ status &= ~(1 << 3);
+ buf[0x24] = status;
+ printf("new character status: %#hhx, bitmap: [", status);
+ for (i = 7; i >= 0; i--) {
+ if (status & (1 << i))
+ putchar('1');
+ else
+ putchar('0');
+ }
+ printf("]\n");
+ }
+ if (hflag) {
+ printf("making character hardcore\n");
+ status |= (1 << 2);
+ buf[0x24] = status;
+ }
+
+ printf("checksum before: %#x\n", *(uint32_t *)&buf[12]);
+ *(uint32_t *)&buf[12] = 0;
+ for (chksum = 0, i = 0; i < sbuf.st_size; i++) {
+ tmp = buf[i];
+ chksum = rotl(chksum, 1);
+ chksum += tmp;
+ }
+ printf("checksum after: %#x\n", chksum);
+ *(uint32_t *)&buf[12] = chksum;
+
+ ret = lseek(fd, 0, SEEK_SET);
+ if (ret < 0)
+ err(1, "lseek");
+
+ printf("writing changes...");
+ if (write(fd, buf, sbuf.st_size) != sbuf.st_size)
+ err(1, "write");
+ printf("OK!\n");
+
+ close(fd);
+ return 0;
+}
diff --git a/get.go b/get.go
@@ -0,0 +1,54 @@
+// Download files over http with go
+// Default to stdout unless [-o outfile] has been specified
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+ "os"
+)
+
+var (
+ outFile = flag.String("o", "", "Output File")
+)
+
+func usage() {
+ fmt.Fprintf(os.Stderr, "usage: %s [-o outfile] url\n", os.Args[0])
+ os.Exit(2)
+}
+
+func main() {
+ log.SetPrefix("get ")
+ flag.Usage = usage
+ flag.Parse()
+
+ args := flag.Args()
+ if len(args) < 1 {
+ usage()
+ }
+
+ var out *os.File
+ if *outFile != "" {
+ o, err := os.Create(*outFile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer o.Close()
+ out = o
+ } else {
+ out = os.Stdout
+ }
+
+ r, err := http.Get(args[0])
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer r.Body.Close()
+ _, err = io.Copy(out, r.Body)
+ if err != nil {
+ log.Fatal(err)
+ }
+}