mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge branch 'master' of https://github.com/dubslow/toxcore
This commit is contained in:
commit
627e4d3aa6
|
@ -241,18 +241,22 @@ already downloaded by other clients can be reused.
|
|||
|
||||
Given the Tox data directory described in STS Draft v0.1.0:
|
||||
|
||||
- The user avatar is stored in a file named "avatar.png". As more formats
|
||||
may be used in the future, another extensions are reserved and clients
|
||||
should keep just one file named "avatar.*", with the data of the last
|
||||
avatar set by the user. If the user have no avatar, no such files should
|
||||
be kept in the data directory;
|
||||
- Avatars are stored in a directory called "avatars" and named
|
||||
as "xxxxx.png", where "xxxxx" is the complete client id (but not friend
|
||||
address!) encoded as an uppercase hexadecimal string and "png" is the
|
||||
extension for the PNG avatar. As new image formats may be used in the
|
||||
future, clients should ensure no other file "xxxxx.*" exists. No file
|
||||
should be kept for an user who have no avatar.
|
||||
|
||||
- Friends avatars are stored in a directory called "avatars" and named
|
||||
as "xxxxx.png", where "xxxxx" is the complete client id encoded as an
|
||||
uppercase hexadecimal string and "png" is the extension for the PNG
|
||||
avatar. As new image formats may be used in the future, clients should
|
||||
ensure no other file "xxxxx.*" exists. No file should be kept for an user
|
||||
who have no avatar.
|
||||
- The client's own avatar is not special and is stored like any other. This
|
||||
is partially for simplicity, and partially in anticipation of profiles.
|
||||
|
||||
- The avatar should be stored as its recieved, before any modifications by
|
||||
the client for display purposes.
|
||||
|
||||
- The hash, as calculated by toxcore and passed in to the data callback,
|
||||
should be saved in "avatars/xxxxx.hash" where "xxxxx" means the
|
||||
same thing as for avatars. (The filename is longer than the file :) )
|
||||
|
||||
**To be discussed:** User keys are usually presented in Tox clients as
|
||||
upper case strings, but lower case file names are more usual.
|
||||
|
@ -262,13 +266,14 @@ Example for Linux and other Unix systems, assuming an user called "gildor":
|
|||
|
||||
Tox data directory: /home/gildor/.config/tox/
|
||||
Tox data file: /home/gildor/.config/tox/data
|
||||
Gildor's avatar: /home/gildor/.config/tox/avatar.png
|
||||
Avatar data dir: /home/gildor/.config/tox/avatars/
|
||||
Gildor's avatar: /home/gildor/.config/tox/avatars/E5809EEF5F11AB29B9BDF543C05B58DDF454AB9CA176C235C7699FDC2757DC33.png
|
||||
Elrond's avatar: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.png
|
||||
Elrond's hash: /home/gildor/.config/tox/avatars/43656C65627269616E20646F6E277420546F782E426164206D656D6F72696573.hash
|
||||
Elladan's avatar: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.png
|
||||
Elladan's hash: /home/gildor/.config/tox/avatars/49486174655768656E48756D616E735468696E6B49416D4D7942726F74686572.hash
|
||||
Elrohir's avatar /home/gildor/.config/tox/avatars/726568746F7242794D6D41496B6E696854736E616D75486E6568576574614849.png
|
||||
Arwen's avatar: /home/gildor/.config/tox/avatars/53686520746F6F6B20476C6F7266696E64656C277320706C6163652068657265.png
|
||||
Lindir's avatar: /home/gildor/.config/tox/avatars/417070735772697474656E42794D6F7274616C734C6F6F6B54686553616D652E.png
|
||||
Elrohir's hash: /home/gildor/.config/tox/avatars/726568746F7242794D6D41496B6E696854736E616D75486E6568576574614849.hash
|
||||
|
||||
This recommendation is partially implemented by "testing/test_avatars.c".
|
||||
|
||||
|
|
|
@ -17,17 +17,15 @@
|
|||
*
|
||||
* Data dir MAY have:
|
||||
*
|
||||
* - A file named avatar.png. If given, the bot will publish it. Otherwise,
|
||||
* no avatar will be set.
|
||||
*
|
||||
* - A directory named "avatars" with the currently cached avatars.
|
||||
* - A directory named "avatars" with the user's avatar and cached avatars.
|
||||
* The user avatar must be named in the format: "<uppercase user id>.png"
|
||||
*
|
||||
*
|
||||
* The bot will answer to these commands:
|
||||
*
|
||||
* !debug-on - Enable extended debug messages
|
||||
* !debug-off - Disenable extended debug messages
|
||||
* !set-avatar - Set our avatar to the contents of the file avatar.*
|
||||
* !set-avatar - Set our avatar from "avatars/<USERID>.png"
|
||||
* !remove-avatar - Remove our avatar
|
||||
*
|
||||
*/
|
||||
|
@ -81,13 +79,12 @@ static void debug_printf(const char *fmt, ...)
|
|||
typedef struct {
|
||||
uint8_t format;
|
||||
char *suffix;
|
||||
char *file_name;
|
||||
} def_avatar_name_t;
|
||||
} avatar_format_data_t;
|
||||
|
||||
static const def_avatar_name_t def_avatar_names[] = {
|
||||
static const avatar_format_data_t avatar_formats[] = {
|
||||
/* In order of preference */
|
||||
{ TOX_AVATAR_FORMAT_PNG, "png", "avatar.png" },
|
||||
{ TOX_AVATAR_FORMAT_NONE, NULL, NULL }, /* Must be the last one */
|
||||
{ TOX_AVATAR_FORMAT_PNG, "png" },
|
||||
{ TOX_AVATAR_FORMAT_NONE, NULL }, /* Must be the last one */
|
||||
};
|
||||
|
||||
|
||||
|
@ -99,9 +96,9 @@ static char *get_avatar_suffix_from_format(uint8_t format)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++)
|
||||
if (def_avatar_names[i].format == format)
|
||||
return def_avatar_names[i].suffix;
|
||||
for (i = 0; avatar_formats[i].format != TOX_AVATAR_FORMAT_NONE; i++)
|
||||
if (avatar_formats[i].format == format)
|
||||
return avatar_formats[i].suffix;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -169,8 +166,8 @@ static void byte_to_hex_str(const uint8_t *buf, const size_t buflen, char *dst)
|
|||
/* Make the cache file name for a avatar of the given format for the given
|
||||
* client id.
|
||||
*/
|
||||
static int make_avatar_file_name(char *dst, size_t dst_len,
|
||||
char *base_dir, uint8_t format, uint8_t *client_id)
|
||||
static int make_avatar_file_name(char *dst, size_t dst_len, const char *base_dir,
|
||||
const uint8_t format, uint8_t *client_id)
|
||||
{
|
||||
char client_id_str[2 * TOX_CLIENT_ID_SIZE + 1];
|
||||
byte_to_hex_str(client_id, TOX_CLIENT_ID_SIZE, client_id_str);
|
||||
|
@ -267,13 +264,13 @@ static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum)
|
|||
/* This iteration is dumb and inefficient */
|
||||
int i;
|
||||
|
||||
for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++) {
|
||||
for (i = 0; avatar_formats[i].format != TOX_AVATAR_FORMAT_NONE; i++) {
|
||||
int ret = make_avatar_file_name(path, sizeof(path), base_dir,
|
||||
def_avatar_names[i].format, addr);
|
||||
avatar_formats[i].format, addr);
|
||||
|
||||
if (ret != 0) {
|
||||
DEBUG("Failed to create avatar path for friend #%d, format %d\n",
|
||||
friendnum, def_avatar_names[i].format);
|
||||
friendnum, avatar_formats[i].format);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -438,66 +435,49 @@ static void friend_request_cb(Tox *tox, const uint8_t *public_key,
|
|||
}
|
||||
|
||||
|
||||
static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name_t *an)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
int n = snprintf(path, sizeof(path), "%s/%s", base_dir, an->file_name);
|
||||
path[sizeof(path) - 1] = '\0';
|
||||
|
||||
if (n >= sizeof(path)) {
|
||||
DEBUG("error: path %s too big\n", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG("trying file %s: ", path);
|
||||
FILE *fp = fopen(path, "rb");
|
||||
|
||||
if (fp != NULL) {
|
||||
uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH];
|
||||
int len = fread(buf, 1, sizeof(buf), fp);
|
||||
|
||||
if (len >= 0 && len <= TOX_AVATAR_MAX_DATA_LENGTH) {
|
||||
int r = tox_set_avatar(tox, an->format, buf, len);
|
||||
DEBUG("%d bytes, tox_set_avatar returned=%d", len, r);
|
||||
|
||||
if (r == 0)
|
||||
printf("Setting avatar file %s\n", path);
|
||||
else
|
||||
printf("Error setting avatar file %s\n", path);
|
||||
} else if (len < 0) {
|
||||
DEBUG("read error %d", len);
|
||||
} else {
|
||||
printf("Avatar file %s if too big (more than %d bytes)",
|
||||
path, TOX_AVATAR_MAX_DATA_LENGTH);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
} else {
|
||||
DEBUG("File %s not found", path);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void set_avatar(Tox *tox, const char *base_dir)
|
||||
{
|
||||
int i;
|
||||
uint8_t addr[TOX_FRIEND_ADDRESS_SIZE];
|
||||
char path[PATH_MAX];
|
||||
uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (def_avatar_names[i].format == TOX_AVATAR_FORMAT_NONE) {
|
||||
tox_get_address(tox, addr);
|
||||
|
||||
int i;
|
||||
for (i = 0; ; i++) {
|
||||
if (avatar_formats[i].format == TOX_AVATAR_FORMAT_NONE) {
|
||||
tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
|
||||
printf("No avatar file found, setting to NONE.\n");
|
||||
return;
|
||||
break;
|
||||
} else {
|
||||
if (try_avatar_file(tox, base_dir, &def_avatar_names[i]) == 0)
|
||||
int ret = make_avatar_file_name(path, sizeof(path), base_dir,
|
||||
avatar_formats[i].format, addr);
|
||||
if (ret < 0) {
|
||||
printf("Failed to generate avatar file name.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Should be unreachable */
|
||||
printf("UNEXPECTED CODE PATH\n");
|
||||
int len = load_avatar_data(path, buf);
|
||||
if (len < 0) {
|
||||
printf("Failed to load avatar data from file: %s\n", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len > TOX_AVATAR_MAX_DATA_LENGTH) {
|
||||
printf("Avatar file %s is too big (more than %d bytes)",
|
||||
path, TOX_AVATAR_MAX_DATA_LENGTH);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = tox_set_avatar(tox, avatar_formats[i].format, buf, len);
|
||||
DEBUG("tox_set_avatar returned=%d", ret);
|
||||
if (ret == 0)
|
||||
printf("Setting avatar from %s (%d bytes).\n", path, len);
|
||||
else
|
||||
printf("Error setting avatar from %s.\n", path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user