Client UTF-8 support.
(login): New parameter utf8. If set, request option utf-8 from server. (expect, recvline): Split recvline() out of expect(). Replace or remove some unhelpful diagnostics. (eight_bit_clean): New. (screen): If eight_bit_clean is set, highlighting is switched with SO/SI. Else characters with MSB set are highlighted. (main): New option -u to request UTF-8 and set eight_bit_clean.
This commit is contained in:
parent
baf416652a
commit
7ef7aa83b8
6 changed files with 55 additions and 16 deletions
|
@ -7,6 +7,9 @@ empire \- Empire client
|
||||||
.BI \-k
|
.BI \-k
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
|
.BI \-u
|
||||||
|
]
|
||||||
|
[
|
||||||
.BI \-2 " outfile"
|
.BI \-2 " outfile"
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
|
@ -37,6 +40,12 @@ the password for your country in the game
|
||||||
.BI \-k
|
.BI \-k
|
||||||
if someone else is connected to your country, kill their connection
|
if someone else is connected to your country, kill their connection
|
||||||
.TP
|
.TP
|
||||||
|
.BI \-u
|
||||||
|
use UTF-8 rather than ASCII character set
|
||||||
|
.IP
|
||||||
|
This requires server version 4.2.21 or later, and a terminal that
|
||||||
|
understands UTF-8.
|
||||||
|
.TP
|
||||||
.BI \-2 " outfile"
|
.BI \-2 " outfile"
|
||||||
redirect output to
|
redirect output to
|
||||||
.I outfile
|
.I outfile
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
expect(int s, int match, char *buf)
|
recvline(int s, char *buf)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -62,7 +62,6 @@ expect(int s, int match, char *buf)
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
n = recv(s, ptr, size, MSG_PEEK);
|
n = recv(s, ptr, size, MSG_PEEK);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
fprintf(stderr, "Expecting code %d\n", match);
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,7 +90,10 @@ expect(int s, int match, char *buf)
|
||||||
}
|
}
|
||||||
ptr += n;
|
ptr += n;
|
||||||
if ((n = recv(s, ptr, size, MSG_PEEK)) <= 0) {
|
if ((n = recv(s, ptr, size, MSG_PEEK)) <= 0) {
|
||||||
fprintf(stderr, "Expecting %d, got %s\n", match, buf);
|
#ifdef _WIN32
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
#endif
|
||||||
|
perror("recv");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
size -= n;
|
size -= n;
|
||||||
|
@ -123,7 +125,7 @@ expect(int s, int match, char *buf)
|
||||||
(void)alarm(0);
|
(void)alarm(0);
|
||||||
#endif
|
#endif
|
||||||
if (!isxdigit(*buf)) {
|
if (!isxdigit(*buf)) {
|
||||||
fprintf(stderr, "Expecting %d, got %s\n", match, buf);
|
fprintf(stderr, "Malformed line %s\n", buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (isdigit(*buf))
|
if (isdigit(*buf))
|
||||||
|
@ -133,9 +135,14 @@ expect(int s, int match, char *buf)
|
||||||
*buf = tolower(*buf);
|
*buf = tolower(*buf);
|
||||||
code = 10 + *buf - 'a';
|
code = 10 + *buf - 'a';
|
||||||
}
|
}
|
||||||
if (code == match)
|
return code;
|
||||||
return 1;
|
}
|
||||||
return 0;
|
|
||||||
|
int
|
||||||
|
expect(int s, int match, char *buf)
|
||||||
|
{
|
||||||
|
int code = recvline(s, buf);
|
||||||
|
return code == match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -44,19 +44,31 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
login(int s, char *uname, char *cname, char *cpass, int kill_proc)
|
login(int s, char *uname, char *cname, char *cpass, int kill_proc, int utf8)
|
||||||
{
|
{
|
||||||
char tmp[128];
|
char tmp[128];
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *p;
|
char *p;
|
||||||
int len;
|
int len, code;
|
||||||
|
|
||||||
if (!expect(s, C_INIT, buf))
|
if (!expect(s, C_INIT, buf))
|
||||||
return 0;
|
return 0;
|
||||||
(void)sendcmd(s, "user", uname);
|
(void)sendcmd(s, "user", uname);
|
||||||
if (!expect(s, C_CMDOK, buf))
|
if (!expect(s, C_CMDOK, buf))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (utf8) {
|
||||||
|
sendcmd(s, "options", "utf-8");
|
||||||
|
for (;;) {
|
||||||
|
code = recvline(s, buf);
|
||||||
|
if (code == C_CMDOK)
|
||||||
|
break;
|
||||||
|
if (code != C_DATA) {
|
||||||
|
fprintf(stderr, "Server doesn't support UTF-8\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (cname == NULL) {
|
if (cname == NULL) {
|
||||||
(void)printf("Country name? ");
|
(void)printf("Country name? ");
|
||||||
cname = fgets(tmp, sizeof(tmp), stdin);
|
cname = fgets(tmp, sizeof(tmp), stdin);
|
||||||
|
|
|
@ -70,6 +70,7 @@ HANDLE hStdIn;
|
||||||
|
|
||||||
#define RETRY 3
|
#define RETRY 3
|
||||||
|
|
||||||
|
int eight_bit_clean;
|
||||||
int interrupt;
|
int interrupt;
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
|
@ -105,6 +106,7 @@ main(int ac, char **av)
|
||||||
char *pname;
|
char *pname;
|
||||||
char *uname;
|
char *uname;
|
||||||
int send_kill = 0;
|
int send_kill = 0;
|
||||||
|
int utf8 = 0;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
err = WSAStartup(0x0101, &WsaData);
|
err = WSAStartup(0x0101, &WsaData);
|
||||||
|
@ -133,6 +135,9 @@ main(int ac, char **av)
|
||||||
} else if (strcmp(ptr, "-k") == 0) {
|
} else if (strcmp(ptr, "-k") == 0) {
|
||||||
send_kill = 1;
|
send_kill = 1;
|
||||||
continue;
|
continue;
|
||||||
|
} else if (strcmp(ptr, "-u") == 0) {
|
||||||
|
utf8 = eight_bit_clean = 1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
argv[j] = argv[i];
|
argv[j] = argv[i];
|
||||||
++j;
|
++j;
|
||||||
|
@ -184,7 +189,7 @@ main(int ac, char **av)
|
||||||
uname = "nobody";
|
uname = "nobody";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!login(sock, uname, cname, pname, send_kill)) {
|
if (!login(sock, uname, cname, pname, send_kill, utf8)) {
|
||||||
close(sock);
|
close(sock);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ struct ioqueue;
|
||||||
|
|
||||||
extern char empirehost[];
|
extern char empirehost[];
|
||||||
extern char empireport[];
|
extern char empireport[];
|
||||||
|
extern int eight_bit_clean;
|
||||||
extern int interrupt;
|
extern int interrupt;
|
||||||
extern char num_teles[];
|
extern char num_teles[];
|
||||||
extern int sock;
|
extern int sock;
|
||||||
|
@ -61,12 +62,13 @@ HANDLE hStdIn;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void getsose(void);
|
void getsose(void);
|
||||||
|
int recvline(int s, char *buf);
|
||||||
int expect(int s, int match, char *buf);
|
int expect(int s, int match, char *buf);
|
||||||
int handleintr(int);
|
int handleintr(int);
|
||||||
int hostaddr(char *name, struct sockaddr_in *addr);
|
int hostaddr(char *name, struct sockaddr_in *addr);
|
||||||
int hostconnect(struct sockaddr_in *addr);
|
int hostconnect(struct sockaddr_in *addr);
|
||||||
int hostport(char *name, struct sockaddr_in *addr);
|
int hostport(char *name, struct sockaddr_in *addr);
|
||||||
int login(int s, char *uname, char *cname, char *cpass, int kill_proc);
|
int login(int s, char *uname, char *cname, char *cpass, int kill_proc, int);
|
||||||
void saveargv(int ac, char **src, char **dst);
|
void saveargv(int ac, char **src, char **dst);
|
||||||
void sendcmd(int s, char *cmd, char *arg);
|
void sendcmd(int s, char *cmd, char *arg);
|
||||||
int sendeof(int sock);
|
int sendeof(int sock);
|
||||||
|
|
|
@ -344,11 +344,15 @@ screen(char *buf)
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
while ((c = *buf++)) {
|
while ((c = *buf++)) {
|
||||||
if (c & 0x80) {
|
if (eight_bit_clean) {
|
||||||
for (sop = SO; putc(*sop, stdout); sop++) ;
|
if (c == 14) fputs(SO, stdout);
|
||||||
(void)putc(c & 0x7f, stdout);
|
else if (c == 15) fputs(SE, stdout);
|
||||||
for (sop = SE; putc(*sop, stdout); sop++) ;
|
else putchar(c);
|
||||||
|
} else if (c & 0x80) {
|
||||||
|
fputs(SO, stdout);
|
||||||
|
putchar(c & 0x7f);
|
||||||
|
fputs(SE, stdout);
|
||||||
} else
|
} else
|
||||||
(void)putc(c, stdout);
|
putchar(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue