Compare commits

...

15 Commits

Author SHA1 Message Date
426db0ede6 add curl_custom_init instead of init curl directly 2024-09-09 15:06:54 +08:00
1e3d3e5a83 fix parise may cause segfault 2024-09-09 14:29:36 +08:00
3f064f651c bind timestamp with enc 2024-09-09 14:03:15 +08:00
7bc3939581 remove some duplicate options 2024-09-09 09:57:25 +08:00
be6fc14981 change curl_get failed behavior 2024-09-09 09:32:26 +08:00
922fcea866 bug fixed: marco DPRINT never work 2024-09-09 08:50:21 +08:00
eca3fb03f2 optimize 2024-09-09 08:40:12 +08:00
6c0d5642ba add exit condition and fix potential memory leak 2024-09-09 08:28:04 +08:00
7ddc6aad72 optimize CMakeLists.txt 2024-09-09 08:00:44 +08:00
be611c26c8 static link libpthread on win32 2024-09-09 07:51:20 +08:00
9353d3dccc Merge pull request 'Fix for windows' (#1) from jinham/LiveParise:main into main
Reviewed-on: #1
2024-09-09 07:06:40 +08:00
710174d6de fix console output
Signed-off-by: hamjin <jinham@qq.com>
2024-09-08 23:39:17 +08:00
187cd014f7 fix build for windows for clion and msys-mingw (clang and gcc)
Signed-off-by: hamjin <jinham@qq.com>
2024-09-08 23:38:41 +08:00
3b13327664 downgrade cmake requirement for clion
Signed-off-by: hamjin <jinham@qq.com>
2024-09-08 23:38:35 +08:00
22be367680 main: check status in curl_get
Signed-off-by: hamjin <jinham@qq.com>
2024-09-08 23:38:14 +08:00
2 changed files with 120 additions and 70 deletions

View File

@@ -1,8 +1,9 @@
cmake_minimum_required(VERSION 3.30)
cmake_minimum_required(VERSION 3.23)
project(Live\ Parise C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
include(FetchContent)
@@ -13,26 +14,16 @@ add_compile_options(
-Wextra
)
if (ENABLE_ASAN)
add_compile_options(
-fsanitize=address
-fsanitize=undefined
-fno-omit-frame-pointer
)
add_link_options(
-fsanitize=address
-fsanitize=undefined
)
message("asan is on. if have any problems, disable it.")
endif ()
# For CURL
set(BUILD_STATIC_LIBS ON)
if (WIN32)
set(CURL_USE_SCHANNEL ON)
endif ()
# For cJSON
set(BUILD_SHARED_AND_STATIC_LIBS ON)
set(ENABLE_CUSTOM_COMPILER_FLAGS OFF)
set(ENABLE_CJSON_TEST OFF)
FetchContent_Declare(
cJSON
@@ -50,4 +41,19 @@ FetchContent_MakeAvailable(cJSON curl)
add_executable(main main.c)
target_include_directories(main PUBLIC ${cJSON_SOURCE_DIR})
target_link_libraries(main cjson-static libcurl_static)
target_link_libraries(main cjson-static libcurl_static pthread)
if (ENABLE_ASAN)
target_link_options(
main BEFORE PUBLIC
-fsanitize=address
-fsanitize=undefined
)
endif ()
if (WIN32)
target_link_options(
main BEFORE PUBLIC
-static
)
endif ()

150
main.c
View File

@@ -17,10 +17,10 @@
sprintf(u, URL, SUBROOMID, enc, timestamp); \
}
#ifdef Debug
#define DPRINT(s, ...) \
#ifndef NDEBUG
#define DPRINT(s, __VA_ARGS__) \
{ \
printf(s, ...); \
printf(s, __VA_ARGS__); \
}
#else
#define DPRINT(s, ...)
@@ -32,20 +32,31 @@ struct memory
size_t size;
};
CURLcode curl_get(const char *, struct memory *);
long long current_timestamp();
struct enc
{
char *enc;
long long timestamp;
};
CURLcode curl_get(CURL *, const char *, struct memory *);
size_t cb(char *, size_t, size_t, void *);
char *get_enc();
struct enc get_enc(CURL *);
void parise(void *);
void exit_handler();
const char ENC_URL[] = "https://lbapi-rk.chaoxing.com/lb/parise/enc/get?subRoomId=%s&timestamp=%llu&ss=%s";
const char URL[] = "https://zhibo.chaoxing.com/apis/live/setLivePariseCountByEnc?subroomId=%s&enc=%s&timestamp=%llu";
const char SUBROOMID[] = "381236458034402305";
const char SS[] = "381237373432790016";
const char DNS[] = "8.8.8.8:53,114.114.114.114:53";
static int flag = 1;
int main(int argc, char *argv[])
{
int thread;
#ifdef WIN32
SetConsoleOutputCP(CP_UTF8);
#endif
if (argc < 2)
thread = 4;
@@ -54,62 +65,67 @@ int main(int argc, char *argv[])
curl_global_init(CURL_GLOBAL_ALL);
printf("线程\t状态\t点赞量\n");
printf("线程\t状态\t点赞量\t(按下回车键退出)\n");
pthread_t **thread_pool = malloc(sizeof(pthread_t *) * thread);
pthread_t *thread_pool = malloc(sizeof(pthread_t) * thread);
for (int i = 0; i < thread; i++)
{
thread_pool[i] = malloc(sizeof(pthread_t));
pthread_create(thread_pool[i], NULL, (void *)&parise, (void *)i);
if (i == thread - 1)
pthread_create(&thread_pool[i], NULL, (void *)&exit_handler, NULL);
else
pthread_create(&thread_pool[i], NULL, (void *)&parise, (void *)i);
}
for (int i = 0; i < thread; i++)
{
pthread_join(*thread_pool[i], NULL);
}
pthread_join(thread_pool[i], NULL);
free(thread_pool);
curl_global_cleanup();
for (int i = 0; i < 8; i++)
{
free(thread_pool[i]);
}
return 0;
}
CURLcode curl_get(const char *const url, struct memory *chunk)
CURLcode curl_custom_init(CURL **curl, struct curl_slist **headers)
{
int status;
CURL *curl = NULL;
struct curl_slist *headers = NULL;
*curl = curl_easy_init();
curl = curl_easy_init();
if (curl == NULL)
if (*curl == NULL)
return CURLE_FAILED_INIT;
headers = curl_slist_append(headers, "Accept: application/json, text/javascript, */*; q=0.01");
headers = curl_slist_append(headers, "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like "
"Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0");
*headers = curl_slist_append(*headers, "Accept: application/json, text/javascript, */*; q=0.01");
*headers =
curl_slist_append(*headers, "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like "
"Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0");
curl_easy_setopt(*curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(*curl, CURLOPT_DNS_SERVERS, DNS);
curl_easy_setopt(*curl, CURLOPT_USE_SSL, true);
curl_easy_setopt(*curl, CURLOPT_WRITEFUNCTION, cb);
return CURLE_OK;
}
CURLcode curl_get(CURL *curl, const char *const url, struct memory *chunk)
{
int status;
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_USE_SSL, true);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)chunk);
status = curl_easy_perform(curl);
if (status != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(status));
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
return status;
}
long long current_timestamp()
{
time_t timestamp = time(NULL);
return timestamp * 1000;
const time_t timestamp = time(NULL);
srand(timestamp);
return timestamp * 1000 + (rand() % 1999 - 999); // -999 ~ 999
}
size_t cb(char *data, size_t size, size_t nmemb, void *clientp)
@@ -122,31 +138,36 @@ size_t cb(char *data, size_t size, size_t nmemb, void *clientp)
return 0; /* out of memory! */
mem->response = ptr;
memcpy(&(mem->response[mem->size]), data, realsize);
memcpy(&mem->response[mem->size], data, realsize);
mem->size += realsize;
mem->response[mem->size] = 0;
return realsize;
}
char *get_enc()
struct enc get_enc(CURL *curl)
{
char url[200];
char *ret = NULL;
struct enc ret = {0};
struct memory data = {0};
const cJSON *enc = NULL;
const cJSON *json = NULL;
cJSON *data_json = NULL;
REGEN_ENC_URL_F(url, current_timestamp());
curl_get(url, &data);
ret.timestamp = current_timestamp();
REGEN_ENC_URL_F(url, ret.timestamp);
if (curl_get(curl, url, &data) != CURLE_OK)
return ret;
DPRINT("%s\n", data.response);
cJSON *data_json = cJSON_Parse(data.response);
enc = cJSON_GetObjectItemCaseSensitive(data_json, "enc");
data_json = cJSON_Parse(data.response);
json = cJSON_GetObjectItemCaseSensitive(data_json, "enc");
const size_t s = strlen(enc->valuestring);
ret = malloc(s + 1);
memcpy(ret, enc->valuestring, s + 1);
const size_t s = strlen(json->valuestring);
ret.enc = malloc(s + 1);
memcpy(ret.enc, json->valuestring, s + 1);
free(data.response);
cJSON_Delete(data_json);
@@ -156,20 +177,33 @@ char *get_enc()
// {'data': 293687, 'msg': '操作成功', 'result': 1}
void parise(void *arg)
{
while (true)
const int idx = (int)arg;
CURL *curl = NULL;
struct curl_slist *headers = NULL;
if (curl_custom_init(&curl, &headers) != CURLE_OK)
{
fprintf(stderr, "T%d: curl_custom_init() failed\n", idx);
return;
}
while (flag)
{
char url[200];
const int idx = (int)arg;
struct memory json_c = {0};
const char *enc = get_enc();
struct enc enc;
const cJSON *result = NULL;
const cJSON *msg = NULL;
const cJSON *data = NULL;
const cJSON *errorMsg = NULL;
cJSON *json = NULL;
if ((enc = get_enc(curl)).enc == NULL)
continue;
REGEN_URL_F(url, enc, current_timestamp());
curl_get(url, &json_c);
REGEN_URL_F(url, enc.enc, enc.timestamp);
if (curl_get(curl, url, &json_c) != CURLE_OK)
goto clean;
json = cJSON_Parse(json_c.response);
result = cJSON_GetObjectItemCaseSensitive(json, "result");
@@ -180,12 +214,22 @@ void parise(void *arg)
if (result->valueint == 1)
printf("\rT%d\t%s\t%d", idx, msg->valuestring, data->valueint);
else
printf("\rT%d\t%s", idx, errorMsg->valuestring);
fprintf(stderr, "\rT%d\t%s", idx, errorMsg->valuestring);
fflush(stdout);
free((void *)enc);
clean:
free(enc.enc);
free(json_c.response);
cJSON_Delete(json);
}
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
printf("\rSignal Received: exit. T%d exiting\n", idx);
}
void exit_handler()
{
getchar();
flag = 0;
}