Beispiel #1
0
void
encode_recur(DBusMessageIter *iter, int *err, const alarm_recur_t *rec)
{
  encode_uint64 (iter, err, &rec->mask_min);
  encode_uint32 (iter, err, &rec->mask_hour);
  encode_uint32 (iter, err, &rec->mask_mday);
  encode_uint32 (iter, err, &rec->mask_wday);
  encode_uint32 (iter, err, &rec->mask_mon);
  encode_uint32 (iter, err, &rec->special);
}
Beispiel #2
0
void EditorExportPlatformOSX::_make_icon(const Image& p_icon,Vector<uint8_t>& icon) {


	Ref<ImageTexture> it = memnew( ImageTexture );
	int size=512;

	Vector<uint8_t> data;

	data.resize(8);
	data[0]='i';
	data[1]='c';
	data[2]='n';
	data[3]='s';

	const char *name[]={"ic09","ic08","ic07","icp6","icp5","icp4"};
	int index=0;

	while(size>=16) {

		Image copy = p_icon;
		copy.convert(Image::FORMAT_RGBA);
		copy.resize(size,size);
		it->create_from_image(copy);
		String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/icon.png";
		ResourceSaver::save(path,it);

		FileAccess *f = FileAccess::open(path,FileAccess::READ);
		ERR_FAIL_COND(!f);

		int ofs = data.size();
		uint32_t len = f->get_len();
		data.resize(data.size()+len+8);
		f->get_buffer(&data[ofs+8],len);
		memdelete(f);
		len+=8;
		len=BSWAP32(len);
		copymem(&data[ofs],name[index],4);
		encode_uint32(len,&data[ofs+4]);
		index++;
		size/=2;
	}

	uint32_t total_len = data.size();
	total_len = BSWAP32(total_len);
	encode_uint32(total_len,&data[4]);

	icon=data;
}
Beispiel #3
0
static int encode_string(lua_State *L) {
	size_t len;
	char *mem;
	const char *str;
	unsigned size;
	
	if (lua_isnil(L, -1)) {
		lua_pushinteger(L, 0);
		encode_uint32(L);
		lua_remove(L, -2);
		return 1;
	}
	
	str = lua_tostring(L, -1);
	len = strlen(str) + 1;
	size = len + sizeof(unsigned);
	mem = (char*)malloc(size);
	
	if (!mem) {
		lua_pushstring(L, "Out of memory!");
		lua_error(L);
	}
	
	memcpy(mem, &len, sizeof(unsigned));
	memcpy(mem + sizeof(unsigned), str, len);
	lua_pushlstring(L, mem, size);
	
	free(mem);
	return 1;
}
Beispiel #4
0
static void encode_layoutstats(struct xdr_stream *xdr,
			       struct nfs42_layoutstat_args *args,
			       struct nfs42_layoutstat_devinfo *devinfo,
			       struct compound_hdr *hdr)
{
	__be32 *p;

	encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
	p = reserve_space(xdr, 8 + 8);
	p = xdr_encode_hyper(p, devinfo->offset);
	p = xdr_encode_hyper(p, devinfo->length);
	encode_nfs4_stateid(xdr, &args->stateid);
	p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
	p = xdr_encode_hyper(p, devinfo->read_count);
	p = xdr_encode_hyper(p, devinfo->read_bytes);
	p = xdr_encode_hyper(p, devinfo->write_count);
	p = xdr_encode_hyper(p, devinfo->write_bytes);
	p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
			NFS4_DEVICEID4_SIZE);
	/* Encode layoutupdate4 */
	*p++ = cpu_to_be32(devinfo->layout_type);
	if (devinfo->layoutstats_encode != NULL)
		devinfo->layoutstats_encode(xdr, args, devinfo);
	else
		encode_uint32(xdr, 0);
}
Beispiel #5
0
DVector<int> TileMap::_get_tile_data() const {

	DVector<int> data;
	data.resize(tile_map.size()*2);
	DVector<int>::Write w = data.write();

	int idx=0;
	for(const Map<PosKey,Cell>::Element *E=tile_map.front();E;E=E->next()) {

		uint8_t *ptr = (uint8_t*)&w[idx];
		encode_uint16(E->key().x,&ptr[0]);
		encode_uint16(E->key().y,&ptr[2]);
		uint32_t val = E->get().id;
		if (E->get().flip_h)
			val|=(1<<29);
		if (E->get().flip_v)
			val|=(1<<30);

		encode_uint32(val,&ptr[4]);
		idx+=2;
	}


	w = DVector<int>::Write();

	return data;

}
Beispiel #6
0
static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
			    const u32 length)
{
	BUG_ON(length > NFS3_MAXPATHLEN);
	encode_uint32(xdr, length);
	xdr_write_pages(xdr, pages, 0, length);
}
void FileAccessNetworkClient::put_32(int p_32) {

	uint8_t buf[4];
	encode_uint32(p_32,buf);
	client->put_data(buf,4);
	DEBUG_PRINT("put32: "+itos(p_32));
}
Beispiel #8
0
static void encode_copy(struct xdr_stream *xdr,
			struct nfs42_copy_args *args,
			struct compound_hdr *hdr)
{
	encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
	encode_nfs4_stateid(xdr, &args->src_stateid);
	encode_nfs4_stateid(xdr, &args->dst_stateid);

	encode_uint64(xdr, args->src_pos);
	encode_uint64(xdr, args->dst_pos);
	encode_uint64(xdr, args->count);

	encode_uint32(xdr, 1); /* consecutive = true */
	encode_uint32(xdr, 1); /* synchronous = true */
	encode_uint32(xdr, 0); /* src server list */
}
Beispiel #9
0
static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
				     struct xdr_stream *xdr,
				     const struct nfs3_setaclargs *args)
{
	unsigned int base;
	int error;

	encode_nfs_fh3(xdr, NFS_FH(args->inode));
	encode_uint32(xdr, args->mask);

	base = req->rq_slen;
	if (args->npages != 0)
		xdr_write_pages(xdr, args->pages, 0, args->len);
	else
		xdr_reserve_space(xdr, NFS_ACL_INLINE_BUFSIZE);

	error = nfsacl_encode(xdr->buf, base, args->inode,
			    (args->mask & NFS_ACL) ?
			    args->acl_access : NULL, 1, 0);
	BUG_ON(error < 0);
	error = nfsacl_encode(xdr->buf, base + error, args->inode,
			    (args->mask & NFS_DFACL) ?
			    args->acl_default : NULL, 1,
			    NFS_ACL_DEFAULT);
	BUG_ON(error < 0);
}
Beispiel #10
0
void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {

	Ref<ImageTexture> it = memnew(ImageTexture);
	int size = 512;

	Vector<uint8_t> data;

	data.resize(8);
	data[0] = 'i';
	data[1] = 'c';
	data[2] = 'n';
	data[3] = 's';

	const char *name[] = { "ic09", "ic08", "ic07", "icp6", "icp5", "icp4" };
	int index = 0;

	while (size >= 16) {

		Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy?
		copy->convert(Image::FORMAT_RGBA8);
		copy->resize(size, size);
		it->create_from_image(copy);
		String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png");
		ResourceSaver::save(path, it);

		FileAccess *f = FileAccess::open(path, FileAccess::READ);
		ERR_FAIL_COND(!f);

		int ofs = data.size();
		uint32_t len = f->get_len();
		data.resize(data.size() + len + 8);
		f->get_buffer(&data[ofs + 8], len);
		memdelete(f);
		len += 8;
		len = BSWAP32(len);
		copymem(&data[ofs], name[index], 4);
		encode_uint32(len, &data[ofs + 4]);
		index++;
		size /= 2;
	}

	uint32_t total_len = data.size();
	total_len = BSWAP32(total_len);
	encode_uint32(total_len, &data[4]);

	p_data = data;
}
Beispiel #11
0
static void encode_seek(struct xdr_stream *xdr,
			struct nfs42_seek_args *args,
			struct compound_hdr *hdr)
{
	encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
	encode_nfs4_stateid(xdr, &args->sa_stateid);
	encode_uint64(xdr, args->sa_offset);
	encode_uint32(xdr, args->sa_what);
}
Beispiel #12
0
void StreamPeer::put_32(int32_t p_val) {

	if (big_endian) {
		p_val = BSWAP32(p_val);
	}
	uint8_t buf[4];
	encode_uint32(p_val, buf);
	put_data(buf, 4);
}
Beispiel #13
0
bool GridMap::_get(const StringName &p_name, Variant &r_ret) const {

	String name = p_name;

	if (name == "theme") {
		r_ret = get_theme();
	} else if (name == "cell_size") {
		r_ret = get_cell_size();
	} else if (name == "cell_octant_size") {
		r_ret = get_octant_size();
	} else if (name == "cell_center_x") {
		r_ret = get_center_x();
	} else if (name == "cell_center_y") {
		r_ret = get_center_y();
	} else if (name == "cell_center_z") {
		r_ret = get_center_z();
	} else if (name == "cell_scale") {
		r_ret = cell_scale;
	} else if (name == "data") {

		Dictionary d;

		PoolVector<int> cells;
		cells.resize(cell_map.size() * 3);
		{
			PoolVector<int>::Write w = cells.write();
			int i = 0;
			for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next(), i++) {

				encode_uint64(E->key().key, (uint8_t *)&w[i * 3]);
				encode_uint32(E->get().cell, (uint8_t *)&w[i * 3 + 2]);
			}
		}

		d["cells"] = cells;

		r_ret = d;
	} else if (name.begins_with("areas/")) {
		int which = name.get_slicec('/', 1).to_int();
		String what = name.get_slicec('/', 2);
		if (what == "bounds")
			r_ret = area_get_bounds(which);
		else if (what == "name")
			r_ret = area_get_name(which);
		else if (what == "disable_distance")
			r_ret = area_get_portal_disable_distance(which);
		else if (what == "exterior_portal")
			r_ret = area_is_exterior_portal(which);
		else
			return false;
	} else
		return false;

	return true;
}
Beispiel #14
0
static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req,
				     struct xdr_stream *xdr,
				     const struct nfs3_getaclargs *args)
{
	encode_nfs_fh3(xdr, args->fh);
	encode_uint32(xdr, args->mask);
	if (args->mask & (NFS_ACL | NFS_DFACL))
		prepare_reply_buffer(req, args->pages, 0,
					NFSACL_MAXPAGES << PAGE_SHIFT,
					ACL3_getaclres_sz);
}
Beispiel #15
0
 int encode_int < uint32_t > ( uint32_t val, uint8_t * start, uint8_t * end )
 {
     int ret = encode_uint32 ( val, start, end );
     if ( ret > 0 )
     {
         uint32_t val2;
         int ret2 = decode_uint32 ( start, start + ret, & val2 );
         assert ( ret == ret2 && val == val2 );
     }
     return ret;
 }
Beispiel #16
0
bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int p_target) {
	bool has_all_peers = true;
	List<int> peers_to_add; // If one is missing, take note to add it.

	for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {

		if (p_target < 0 && E->get() == -p_target)
			continue; // Continue, excluded.

		if (p_target > 0 && E->get() != p_target)
			continue; // Continue, not for this peer.

		Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());

		if (!F || !F->get()) {
			// Path was not cached, or was cached but is unconfirmed.
			if (!F) {
				// Not cached at all, take note.
				peers_to_add.push_back(E->get());
			}

			has_all_peers = false;
		}
	}

	// Those that need to be added, send a message for this.

	for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) {

		// Encode function name.
		CharString pname = String(p_path).utf8();
		int len = encode_cstring(pname.get_data(), NULL);

		Vector<uint8_t> packet;

		packet.resize(1 + 4 + len);
		packet.write[0] = NETWORK_COMMAND_SIMPLIFY_PATH;
		encode_uint32(psc->id, &packet.write[1]);
		encode_cstring(pname.get_data(), &packet.write[5]);

		network_peer->set_target_peer(E->get()); // To all of you.
		network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
		network_peer->put_packet(packet.ptr(), packet.size());

		psc->confirmed_peers.insert(E->get(), false); // Insert into confirmed, but as false since it was not confirmed.
	}

	return has_all_peers;
}
Beispiel #17
0
/** The twofish packet format consists of:
 *
 *  - a 8-bit twofish encoding version in clear text
 *  - a 32-bit SA number in clear text
 *  - ciphertext encrypted from a 32-bit nonce followed by the payload.
 *
 *  [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD]
 *         |<------ encrypted ------>|
 */
static int transop_encode_twofish( ntvl_trans_op_t * arg,
                                   uint8_t * outbuf,
                                   size_t out_len,
                                   const uint8_t * inbuf,
                                   size_t in_len ) {
    int len=-1;
    transop_tf_t * priv = (transop_tf_t *)arg->priv;
    uint8_t assembly[NTVL_PKT_BUF_SIZE];
    uint32_t * pnonce;

    if ( (in_len + TRANSOP_TF_NONCE_SIZE) <= NTVL_PKT_BUF_SIZE ) {
        if ( (in_len + TRANSOP_TF_NONCE_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_VER_SIZE) <= out_len ) {
            size_t idx=0;
            sa_twofish_t * sa;
            size_t tx_sa_num = 0;

            /* The transmit sa is periodically updated */
            tx_sa_num = tf_choose_tx_sa( priv );

            sa = &(priv->sa[tx_sa_num]); /* Proper Tx SA index */

            traceEvent( TRACE_DEBUG, "encode_twofish %lu with SA %lu.", in_len, sa->sa_id );

            /* Encode the twofish format version. */
            encode_uint8( outbuf, &idx, NTVL_TWOFISH_TRANSFORM_VERSION );

            /* Encode the security association (SA) number */
            encode_uint32( outbuf, &idx, sa->sa_id );

            /* The assembly buffer is a source for encrypting data. The nonce is
             * written in first followed by the packet payload. The whole
             * contents of assembly are encrypted. */
            pnonce = (uint32_t *)assembly;
            *pnonce = rand();
            memcpy( assembly + TRANSOP_TF_NONCE_SIZE, inbuf, in_len );

            /* Encrypt the assembly contents and write the ciphertext after the SA. */
            len = TwoFishEncryptRaw( assembly, /* source */
                                     outbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE,
                                     in_len + TRANSOP_TF_NONCE_SIZE, /* enc size */
                                     sa->enc_tf);
            if ( len > 0 ) len += TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE; /* size of data carried in UDP. */
            else traceEvent( TRACE_ERROR, "encode_twofish encryption failed." );
        } else traceEvent( TRACE_ERROR, "encode_twofish outbuf too small." );
    } else traceEvent( TRACE_ERROR, "encode_twofish inbuf too big to encrypt." );

    return len;
}
Beispiel #18
0
static void encode_createhow3(struct xdr_stream *xdr,
			      const struct nfs3_createargs *args)
{
	encode_uint32(xdr, args->createmode);
	switch (args->createmode) {
	case NFS3_CREATE_UNCHECKED:
	case NFS3_CREATE_GUARDED:
		encode_sattr3(xdr, args->sattr);
		break;
	case NFS3_CREATE_EXCLUSIVE:
		encode_createverf3(xdr, args->verifier);
		break;
	default:
		BUG();
	}
}
Beispiel #19
0
static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) {

	CharString utf8 = p_string.utf8();

	if (buf) {
		encode_uint32(utf8.length(), buf);
		buf += 4;
		copymem(buf, utf8.get_data(), utf8.length());
		buf += utf8.length();
	}

	r_len += 4 + utf8.length();
	while (r_len % 4) {
		r_len++; //pad
		if (buf) {
			buf++;
		}
	}
}
Beispiel #20
0
bool GridMap::_get(const StringName &p_name, Variant &r_ret) const {

	String name = p_name;

	if (name == "theme") {
		r_ret = get_theme();
	} else if (name == "cell_size") {
		r_ret = get_cell_size();
	} else if (name == "cell_octant_size") {
		r_ret = get_octant_size();
	} else if (name == "cell_center_x") {
		r_ret = get_center_x();
	} else if (name == "cell_center_y") {
		r_ret = get_center_y();
	} else if (name == "cell_center_z") {
		r_ret = get_center_z();
	} else if (name == "cell_scale") {
		r_ret = cell_scale;
	} else if (name == "data") {

		Dictionary d;

		PoolVector<int> cells;
		cells.resize(cell_map.size() * 3);
		{
			PoolVector<int>::Write w = cells.write();
			int i = 0;
			for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next(), i++) {

				encode_uint64(E->key().key, (uint8_t *)&w[i * 3]);
				encode_uint32(E->get().cell, (uint8_t *)&w[i * 3 + 2]);
			}
		}

		d["cells"] = cells;

		r_ret = d;
	} else
		return false;

	return true;
}
Beispiel #21
0
Error PacketPeerStream::put_packet(const uint8_t *p_buffer,int p_buffer_size) {

	ERR_FAIL_COND_V(peer.is_null(),ERR_UNCONFIGURED);
	Error err = _poll_buffer(); //won't hurt to poll here too

	if (err)
		return err;

	if (p_buffer_size==0)
		return OK;

	ERR_FAIL_COND_V( p_buffer_size<0, ERR_INVALID_PARAMETER);
	ERR_FAIL_COND_V( p_buffer_size+4 > temp_buffer.size(), ERR_INVALID_PARAMETER );

	encode_uint32(p_buffer_size,&temp_buffer[0]);
	uint8_t *dst=&temp_buffer[4];
	for(int i=0;i<p_buffer_size;i++)
		dst[i]=p_buffer[i];

	return peer->put_data(&temp_buffer[0],p_buffer_size+4);
}
Beispiel #22
0
/*
 * Initialize and return open socket.
 */
static int
init(void)
{
    int sockfd;
    uint32_t lport;
    uint32_t rport;
    char lhost[NI_MAXHOST];
    char rhost[NI_MAXHOST];

    if (is_client())
        client_get_hosts(lhost, rhost);
    else
        server_get_hosts(lhost, rhost);
    sockfd = rds_socket(lhost, Req.port);
    lport = get_socket_port(sockfd);
    encode_uint32(&lport, lport);
    send_mesg(&lport, sizeof(lport), "RDS port");
    recv_mesg(&rport, sizeof(rport), "RDS port");
    rport = decode_uint32(&rport);
    rds_makeaddr(&RAddr, &RLen, rhost, rport);
    return sockfd;
}
Beispiel #23
0
/*
 * Have an exchange with the client over TCP/IP and get the IP of our local
 * host.
 */
static void
server_get_hosts(char *lhost, char *rhost)
{
    int fd, lfd;
    uint32_t port;
    struct sockaddr_in laddr, raddr;
    socklen_t rlen;

    lfd = socket(AF_INET, SOCK_STREAM, 0);
    if (lfd < 0)
        error(SYS, "socket failed");
    setsockopt_one(lfd, SO_REUSEADDR);

    memset(&laddr, 0, sizeof(laddr));
    laddr.sin_family = AF_INET;
    laddr.sin_addr.s_addr = INADDR_ANY;
    laddr.sin_port = htons(0);
    if (bind(lfd, (SA *)&laddr, sizeof(laddr)) < 0)
        error(SYS, "bind INET failed");

    port = get_socket_port(lfd);
    encode_uint32(&port, port);
    send_mesg(&port, sizeof(port), "TCP IPv4 server port");

    if (listen(lfd, 1) < 0)
        error(SYS, "listen failed");

    rlen = sizeof(raddr);
    fd = accept(lfd, (SA *)&raddr, &rlen);
    if (fd < 0)
        error(SYS, "accept failed");
    close(lfd);
    get_socket_ip((SA *)&raddr, rlen, rhost, NI_MAXHOST);
    send_mesg(rhost, NI_MAXHOST, "client IP");
    recv_mesg(lhost, NI_MAXHOST, "server IP");
    close(fd);
}
Beispiel #24
0
void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount) {

	if (network_peer.is_null()) {
		ERR_EXPLAIN("Attempt to remote call/set when networking is not active in SceneTree.");
		ERR_FAIL();
	}

	if (network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_CONNECTING) {
		ERR_EXPLAIN("Attempt to remote call/set when networking is not connected yet in SceneTree.");
		ERR_FAIL();
	}

	if (network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED) {
		ERR_EXPLAIN("Attempt to remote call/set when networking is disconnected.");
		ERR_FAIL();
	}

	if (p_argcount > 255) {
		ERR_EXPLAIN("Too many arguments >255.");
		ERR_FAIL();
	}

	if (p_to != 0 && !connected_peers.has(ABS(p_to))) {
		if (p_to == network_peer->get_unique_id()) {
			ERR_EXPLAIN("Attempt to remote call/set yourself! unique ID: " + itos(network_peer->get_unique_id()));
		} else {
			ERR_EXPLAIN("Attempt to remote call unexisting ID: " + itos(p_to));
		}

		ERR_FAIL();
	}

	NodePath from_path = (root_node->get_path()).rel_path_to(p_from->get_path());
	ERR_EXPLAIN("Unable to send RPC. Relative path is empty. THIS IS LIKELY A BUG IN THE ENGINE!");
	ERR_FAIL_COND(from_path.is_empty());

	// See if the path is cached.
	PathSentCache *psc = path_send_cache.getptr(from_path);
	if (!psc) {
		// Path is not cached, create.
		path_send_cache[from_path] = PathSentCache();
		psc = path_send_cache.getptr(from_path);
		psc->id = last_send_cache_id++;
	}

	// Create base packet, lots of hardcode because it must be tight.

	int ofs = 0;

#define MAKE_ROOM(m_amount) \
	if (packet_cache.size() < m_amount) packet_cache.resize(m_amount);

	// Encode type.
	MAKE_ROOM(1);
	packet_cache.write[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
	ofs += 1;

	// Encode ID.
	MAKE_ROOM(ofs + 4);
	encode_uint32(psc->id, &(packet_cache.write[ofs]));
	ofs += 4;

	// Encode function name.
	CharString name = String(p_name).utf8();
	int len = encode_cstring(name.get_data(), NULL);
	MAKE_ROOM(ofs + len);
	encode_cstring(name.get_data(), &(packet_cache.write[ofs]));
	ofs += len;

	if (p_set) {
		// Set argument.
		Error err = encode_variant(*p_arg[0], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed());
		ERR_EXPLAIN("Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!");
		ERR_FAIL_COND(err != OK);
		MAKE_ROOM(ofs + len);
		encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
		ofs += len;

	} else {
		// Call arguments.
		MAKE_ROOM(ofs + 1);
		packet_cache.write[ofs] = p_argcount;
		ofs += 1;
		for (int i = 0; i < p_argcount; i++) {
			Error err = encode_variant(*p_arg[i], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed());
			ERR_EXPLAIN("Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
			ERR_FAIL_COND(err != OK);
			MAKE_ROOM(ofs + len);
			encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
			ofs += len;
		}
	}

	// See if all peers have cached path (is so, call can be fast).
	bool has_all_peers = _send_confirm_path(from_path, psc, p_to);

	// Take chance and set transfer mode, since all send methods will use it.
	network_peer->set_transfer_mode(p_unreliable ? NetworkedMultiplayerPeer::TRANSFER_MODE_UNRELIABLE : NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);

	if (has_all_peers) {

		// They all have verified paths, so send fast.
		network_peer->set_target_peer(p_to); // To all of you.
		network_peer->put_packet(packet_cache.ptr(), ofs); // A message with love.
	} else {
		// Not all verified path, so send one by one.

		// Append path at the end, since we will need it for some packets.
		CharString pname = String(from_path).utf8();
		int path_len = encode_cstring(pname.get_data(), NULL);
		MAKE_ROOM(ofs + path_len);
		encode_cstring(pname.get_data(), &(packet_cache.write[ofs]));

		for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {

			if (p_to < 0 && E->get() == -p_to)
				continue; // Continue, excluded.

			if (p_to > 0 && E->get() != p_to)
				continue; // Continue, not for this peer.

			Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
			ERR_CONTINUE(!F); // Should never happen.

			network_peer->set_target_peer(E->get()); // To this one specifically.

			if (F->get()) {
				// This one confirmed path, so use id.
				encode_uint32(psc->id, &(packet_cache.write[1]));
				network_peer->put_packet(packet_cache.ptr(), ofs);
			} else {
				// This one did not confirm path yet, so use entire path (sorry!).
				encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); // Offset to path and flag.
				network_peer->put_packet(packet_cache.ptr(), ofs + path_len);
			}
		}
	}
}
Beispiel #25
0
Vector<uint8_t> GDTokenizerBuffer::parse_code_string(const String& p_code) {

	Vector<uint8_t> buf;


	Map<StringName,int> identifier_map;
	HashMap<Variant,int,VariantHasher> constant_map;
	Map<uint32_t,int> line_map;
	Vector<uint32_t> token_array;

	GDTokenizerText tt;
	tt.set_code(p_code);
	int line=-1;
	int col=0;

	while(true) {

		if (tt.get_token_line()!=line) {

			line=tt.get_token_line();
			line_map[line]=token_array.size();
		}

		uint32_t token=tt.get_token();
		switch(tt.get_token()) {

			case TK_IDENTIFIER: {
				StringName id = tt.get_token_identifier();
				if (!identifier_map.has(id)) {
					int idx = identifier_map.size();
					identifier_map[id]=idx;
				}
				token|=identifier_map[id]<<TOKEN_BITS;
			} break;
			case TK_CONSTANT: {

				Variant c = tt.get_token_constant();
				if (!constant_map.has(c)) {
					int idx = constant_map.size();
					constant_map[c]=idx;
				}
				token|=constant_map[c]<<TOKEN_BITS;
			} break;
			case TK_BUILT_IN_TYPE: {

				token|=tt.get_token_type()<<TOKEN_BITS;
			} break;
			case TK_BUILT_IN_FUNC: {

				token|=tt.get_token_built_in_func()<<TOKEN_BITS;

			} break;
			case TK_NEWLINE: {

				token|=tt.get_token_line_indent()<<TOKEN_BITS;
			} break;
			case TK_ERROR: {

				ERR_FAIL_V(Vector<uint8_t>());
			} break;
			default: {}

		};

		token_array.push_back(token);

		if (tt.get_token()==TK_EOF)
			break;
		tt.advance();

	}

	//reverse maps

	Map<int,StringName> rev_identifier_map;
	for(Map<StringName,int>::Element *E=identifier_map.front();E;E=E->next()) {
		rev_identifier_map[E->get()]=E->key();
	}

	Map<int,Variant> rev_constant_map;
	const Variant *K =NULL;
	while((K=constant_map.next(K))) {
		rev_constant_map[constant_map[*K]]=*K;
	}

	Map<int,uint32_t> rev_line_map;
	for(Map<uint32_t,int>::Element *E=line_map.front();E;E=E->next()) {
		rev_line_map[E->get()]=E->key();
	}

	//save header
	buf.resize(24);
	buf[0]='G';
	buf[1]='D';
	buf[2]='S';
	buf[3]='C';
	encode_uint32(BYTECODE_VERSION,&buf[4]);
	encode_uint32(identifier_map.size(),&buf[8]);
	encode_uint32(constant_map.size(),&buf[12]);
	encode_uint32(line_map.size(),&buf[16]);
	encode_uint32(token_array.size(),&buf[20]);

	//save identifiers

	for(Map<int,StringName>::Element *E=rev_identifier_map.front();E;E=E->next()) {

		CharString cs = String(E->get()).utf8();
		int len = cs.length()+1;
		int extra = 4-(len%4);
		if (extra==4)
			extra=0;

		uint8_t ibuf[4];
		encode_uint32(len+extra,ibuf);
		for(int i=0;i<4;i++) {
			buf.push_back(ibuf[i]);
		}
		for(int i=0;i<len;i++) {
			buf.push_back(cs[i]^0xb6);
		}
		for(int i=0;i<extra;i++) {
			buf.push_back(0^0xb6);
		}
	}

	for(Map<int,Variant>::Element *E=rev_constant_map.front();E;E=E->next()) {

		int len;
		Error err = encode_variant(E->get(),NULL,len);
		ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>());
		int pos=buf.size();
		buf.resize(pos+len);
		encode_variant(E->get(),&buf[pos],len);
	}

	for(Map<int,uint32_t>::Element *E=rev_line_map.front();E;E=E->next()) {

		uint8_t ibuf[8];
		encode_uint32(E->key(),&ibuf[0]);
		encode_uint32(E->get(),&ibuf[4]);
		for(int i=0;i<8;i++)
			buf.push_back(ibuf[i]);
	}

	for(int i=0;i<token_array.size();i++) {

		uint32_t token = token_array[i];

		if (token&~TOKEN_MASK) {
			uint8_t buf4[4];
			encode_uint32(token_array[i]|TOKEN_BYTE_MASK,&buf4[0]);
			for(int j=0;j<4;j++) {
				buf.push_back(buf4[j]);
			}
		} else {
			buf.push_back(token);
		}
	}

	return buf;

}
void NetworkedMultiplayerENet::poll(){

	ERR_FAIL_COND(!active);

	_pop_current_packet();

	ENetEvent event;
	/* Wait up to 1000 milliseconds for an event. */
	while (true) {

		if (!host || !active) //might have been disconnected while emitting a notification
			return;

		int ret = enet_host_service (host, & event, 1);

		if (ret<0) {
			//error, do something?
			break;
		} else if (ret==0) {
			break;
		}

		switch (event.type)
		{
			case ENET_EVENT_TYPE_CONNECT: {
				/* Store any relevant client information here. */

				if (server && refuse_connections) {
					enet_peer_reset(event.peer);
					break;
				}

				IP_Address ip;
				ip.host=event.peer -> address.host;

				int *new_id = memnew( int );
				*new_id = event.data;

				if (*new_id==0) { //data zero is sent by server (enet won't let you configure this). Server is always 1
					*new_id=1;
				}

				event.peer->data=new_id;

				peer_map[*new_id]=event.peer;

				connection_status=CONNECTION_CONNECTED; //if connecting, this means it connected t something!

				emit_signal("peer_connected",*new_id);

				if (server) {
					//someone connected, let it know of all the peers available
					for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) {

						if (E->key()==*new_id)
							continue;
						//send existing peers to new peer
						ENetPacket * packet = enet_packet_create (NULL,8,ENET_PACKET_FLAG_RELIABLE);
						encode_uint32(SYSMSG_ADD_PEER,&packet->data[0]);
						encode_uint32(E->key(),&packet->data[4]);
						enet_peer_send(event.peer,1,packet);
						//send the new peer to existing peers
						packet = enet_packet_create (NULL,8,ENET_PACKET_FLAG_RELIABLE);
						encode_uint32(SYSMSG_ADD_PEER,&packet->data[0]);
						encode_uint32(*new_id,&packet->data[4]);
						enet_peer_send(E->get(),1,packet);
					}
				} else {

					emit_signal("connection_succeeded");
				}

			} break;
			case ENET_EVENT_TYPE_DISCONNECT: {

				/* Reset the peer's client information. */

				int *id = (int*)event.peer -> data;



				if (!id) {
					if (!server) {
						emit_signal("connection_failed");
					}
				} else {

					if (server) {
						//someone disconnected, let it know to everyone else
						for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) {

							if (E->key()==*id)
								continue;
							//send the new peer to existing peers
							ENetPacket* packet = enet_packet_create (NULL,8,ENET_PACKET_FLAG_RELIABLE);
							encode_uint32(SYSMSG_REMOVE_PEER,&packet->data[0]);
							encode_uint32(*id,&packet->data[4]);
							enet_peer_send(E->get(),1,packet);
						}
					} else if (!server) {
						emit_signal("server_disconnected");
						close_connection();
						return;
					}

					emit_signal("peer_disconnected",*id);
					peer_map.erase(*id);
					memdelete( id );

				}


			} break;
			case ENET_EVENT_TYPE_RECEIVE: {


				if (event.channelID==1) {
					//some config message
					ERR_CONTINUE( event.packet->dataLength < 8);

					int msg = decode_uint32(&event.packet->data[0]);
					int id = decode_uint32(&event.packet->data[4]);

					switch(msg) {
						case SYSMSG_ADD_PEER: {

							peer_map[id]=NULL;
							emit_signal("peer_connected",id);

						} break;
						case SYSMSG_REMOVE_PEER: {

							peer_map.erase(id);
							emit_signal("peer_disconnected",id);
						} break;
					}

					enet_packet_destroy(event.packet);
				} else if (event.channelID==0){

					Packet packet;
					packet.packet = event.packet;

					int *id = (int*)event.peer -> data;

					ERR_CONTINUE(event.packet->dataLength<12)


					uint32_t source = decode_uint32(&event.packet->data[0]);
					int target = decode_uint32(&event.packet->data[4]);
					uint32_t flags = decode_uint32(&event.packet->data[8]);

					packet.from=source;

					if (server) {

						packet.from=*id;

						if (target==0) {
							//re-send the everyone but sender :|

							incoming_packets.push_back(packet);
							//and make copies for sending
							for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) {

								if (uint32_t(E->key())==source) //do not resend to self
									continue;

								ENetPacket* packet2 = enet_packet_create (packet.packet->data,packet.packet->dataLength,flags);

								enet_peer_send(E->get(),0,packet2);
							}

						} else if (target<0) {
							//to all but one

							//and make copies for sending
							for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) {

								if (uint32_t(E->key())==source || E->key()==-target) //do not resend to self, also do not send to excluded
									continue;

								ENetPacket* packet2 = enet_packet_create (packet.packet->data,packet.packet->dataLength,flags);

								enet_peer_send(E->get(),0,packet2);
							}

							if (-target != 1) {
								//server is not excluded
								incoming_packets.push_back(packet);
							} else {
								//server is excluded, erase packet
								enet_packet_destroy(packet.packet);
							}

						} else if (target==1) {
							//to myself and only myself
							incoming_packets.push_back(packet);
						} else {
							//to someone else, specifically
							ERR_CONTINUE(!peer_map.has(target));
							enet_peer_send(peer_map[target],0,packet.packet);
						}
					} else {

						incoming_packets.push_back(packet);
					}


					//destroy packet later..
				} else {
					ERR_CONTINUE(true);
				}


			}break;
			case ENET_EVENT_TYPE_NONE: {
				//do nothing
			} break;
		}
	}
}
Beispiel #27
0
void EditorFileServer::_subthread_start(void *s) {

	ClientData *cd = (ClientData *)s;

	cd->connection->set_nodelay(true);
	uint8_t buf4[8];
	Error err = cd->connection->get_data(buf4, 4);
	if (err != OK) {
		_close_client(cd);
		ERR_FAIL_COND(err != OK);
	}

	int passlen = decode_uint32(buf4);

	if (passlen > 512) {

		_close_client(cd);
		ERR_FAIL_COND(passlen > 512);
	} else if (passlen > 0) {

		Vector<char> passutf8;
		passutf8.resize(passlen + 1);
		err = cd->connection->get_data((uint8_t *)passutf8.ptr(), passlen);
		if (err != OK) {
			_close_client(cd);
			ERR_FAIL_COND(err != OK);
		}
		passutf8[passlen] = 0;
		String s;
		s.parse_utf8(passutf8.ptr());
		if (s != cd->efs->password) {
			encode_uint32(ERR_INVALID_DATA, buf4);
			cd->connection->put_data(buf4, 4);
			OS::get_singleton()->delay_usec(1000000);
			_close_client(cd);
			ERR_PRINT("CLIENT PASSWORD MISMATCH");
			ERR_FAIL();
		}
	} else {
		if (cd->efs->password != "") {
			encode_uint32(ERR_INVALID_DATA, buf4);
			cd->connection->put_data(buf4, 4);
			OS::get_singleton()->delay_usec(1000000);
			_close_client(cd);
			ERR_PRINT("CLIENT PASSWORD MISMATCH (should be empty!)");
			ERR_FAIL();
		}
	}

	encode_uint32(OK, buf4);
	cd->connection->put_data(buf4, 4);

	while (!cd->quit) {

		//wait for ID
		err = cd->connection->get_data(buf4, 4);
		//#define DEBUG_PRINT(m_p) print_line(m_p)
		DEBUG_TIME("get_data")

		if (err != OK) {
			_close_client(cd);
			ERR_FAIL_COND(err != OK);
		}
		int id = decode_uint32(buf4);

		//wait for command
		err = cd->connection->get_data(buf4, 4);
		if (err != OK) {
			_close_client(cd);
			ERR_FAIL_COND(err != OK);
		}
		int cmd = decode_uint32(buf4);

		switch (cmd) {

			case FileAccessNetwork::COMMAND_FILE_EXISTS:
			case FileAccessNetwork::COMMAND_GET_MODTIME:
			case FileAccessNetwork::COMMAND_OPEN_FILE: {

				DEBUG_TIME("open_file")
				err = cd->connection->get_data(buf4, 4);
				if (err != OK) {
					_close_client(cd);
					ERR_FAIL_COND(err != OK);
				}

				int namelen = decode_uint32(buf4);
				Vector<char> fileutf8;
				fileutf8.resize(namelen + 1);
				err = cd->connection->get_data((uint8_t *)fileutf8.ptr(), namelen);
				if (err != OK) {
					_close_client(cd);
					ERR_FAIL_COND(err != OK);
				}
				fileutf8[namelen] = 0;
				String s;
				s.parse_utf8(fileutf8.ptr());

				if (cmd == FileAccessNetwork::COMMAND_FILE_EXISTS) {
					print_line("FILE EXISTS: " + s);
				}
				if (cmd == FileAccessNetwork::COMMAND_GET_MODTIME) {
					print_line("MOD TIME: " + s);
				}
				if (cmd == FileAccessNetwork::COMMAND_OPEN_FILE) {
					print_line("OPEN: " + s);
				}

				if (!s.begins_with("res://")) {

					_close_client(cd);
					ERR_FAIL_COND(!s.begins_with("res://"));
				}
				ERR_CONTINUE(cd->files.has(id));

				if (cmd == FileAccessNetwork::COMMAND_FILE_EXISTS) {

					encode_uint32(id, buf4);
					cd->connection->put_data(buf4, 4);
					encode_uint32(FileAccessNetwork::RESPONSE_FILE_EXISTS, buf4);
					cd->connection->put_data(buf4, 4);
					encode_uint32(FileAccess::exists(s), buf4);
					cd->connection->put_data(buf4, 4);
					DEBUG_TIME("open_file_end")
					break;
				}

				if (cmd == FileAccessNetwork::COMMAND_GET_MODTIME) {

					encode_uint32(id, buf4);
					cd->connection->put_data(buf4, 4);
					encode_uint32(FileAccessNetwork::RESPONSE_GET_MODTIME, buf4);
					cd->connection->put_data(buf4, 4);
					encode_uint64(FileAccess::get_modified_time(s), buf4);
					cd->connection->put_data(buf4, 8);
					DEBUG_TIME("open_file_end")
					break;
				}

				FileAccess *fa = FileAccess::open(s, FileAccess::READ);
				if (!fa) {
					//not found, continue
					encode_uint32(id, buf4);
					cd->connection->put_data(buf4, 4);
					encode_uint32(FileAccessNetwork::RESPONSE_OPEN, buf4);
					cd->connection->put_data(buf4, 4);
					encode_uint32(ERR_FILE_NOT_FOUND, buf4);
					cd->connection->put_data(buf4, 4);
					DEBUG_TIME("open_file_end")
					break;
				}

				encode_uint32(id, buf4);
				cd->connection->put_data(buf4, 4);
				encode_uint32(FileAccessNetwork::RESPONSE_OPEN, buf4);
				cd->connection->put_data(buf4, 4);
				encode_uint32(OK, buf4);
				cd->connection->put_data(buf4, 4);
				encode_uint64(fa->get_len(), buf4);
				cd->connection->put_data(buf4, 8);

				cd->files[id] = fa;
				DEBUG_TIME("open_file_end")

			} break;
Beispiel #28
0
void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest) {


	const int CHUNK_AXML_FILE = 0x00080003;
	const int CHUNK_RESOURCEIDS = 0x00080180;
	const int CHUNK_STRINGS = 0x001C0001;
	const int CHUNK_XML_END_NAMESPACE = 0x00100101;
	const int CHUNK_XML_END_TAG = 0x00100103;
	const int CHUNK_XML_START_NAMESPACE = 0x00100100;
	const int CHUNK_XML_START_TAG = 0x00100102;
	const int CHUNK_XML_TEXT = 0x00100104;
	const int UTF8_FLAG = 0x00000100;

	Vector<String> string_table;

	uint32_t ofs=0;


	uint32_t header = decode_uint32(&p_manifest[ofs]);
	uint32_t filesize = decode_uint32(&p_manifest[ofs+4]);
	ofs+=8;

//	print_line("FILESIZE: "+itos(filesize)+" ACTUAL: "+itos(p_manifest.size()));

	uint32_t string_count;
	uint32_t styles_count;
	uint32_t string_flags;
	uint32_t string_data_offset;

	uint32_t styles_offset;
	uint32_t string_table_begins;
	uint32_t string_table_ends;
	Vector<uint8_t> stable_extra;

	while(ofs < p_manifest.size()) {

		uint32_t chunk = decode_uint32(&p_manifest[ofs]);
		uint32_t size = decode_uint32(&p_manifest[ofs+4]);


		switch(chunk) {

			case CHUNK_STRINGS: {


				int iofs=ofs+8;

				uint32_t string_count=decode_uint32(&p_manifest[iofs]);
				uint32_t styles_count=decode_uint32(&p_manifest[iofs+4]);
				uint32_t string_flags=decode_uint32(&p_manifest[iofs+8]);
				uint32_t string_data_offset=decode_uint32(&p_manifest[iofs+12]);
				uint32_t styles_offset=decode_uint32(&p_manifest[iofs+16]);
/*
				printf("string count: %i\n",string_count);
				printf("flags: %i\n",string_flags);
				printf("sdata ofs: %i\n",string_data_offset);
				printf("styles ofs: %i\n",styles_offset);
*/
				uint32_t st_offset=iofs+20;
				string_table.resize(string_count);
				uint32_t string_end=0;

				string_table_begins=st_offset;


				for(int i=0;i<string_count;i++) {

					uint32_t string_at = decode_uint32(&p_manifest[st_offset+i*4]);
					string_at+=st_offset+string_count*4;

					ERR_EXPLAIN("Unimplemented, can't read utf8 string table.");
					ERR_FAIL_COND(string_flags&UTF8_FLAG);

					if (string_flags&UTF8_FLAG) {



					} else {
						uint32_t len = decode_uint16(&p_manifest[string_at]);
						Vector<CharType> ucstring;
						ucstring.resize(len+1);
						for(int j=0;j<len;j++) {
							uint16_t c=decode_uint16(&p_manifest[string_at+2+2*j]);
							ucstring[j]=c;
						}
						string_end=MAX(string_at+2+2*len,string_end);
						ucstring[len]=0;
						string_table[i]=ucstring.ptr();
					}


//					print_line("String "+itos(i)+": "+string_table[i]);
				}

				for(int i=string_end;i<(ofs+size);i++) {
					stable_extra.push_back(p_manifest[i]);
				}

//				printf("stable extra: %i\n",int(stable_extra.size()));
				string_table_ends=ofs+size;

//				print_line("STABLE SIZE: "+itos(size)+" ACTUAL: "+itos(string_table_ends));

			} break;
			case CHUNK_XML_START_TAG: {

				int iofs=ofs+8;
				uint32_t line=decode_uint32(&p_manifest[iofs]);
				uint32_t nspace=decode_uint32(&p_manifest[iofs+8]);
				uint32_t name=decode_uint32(&p_manifest[iofs+12]);
				uint32_t check=decode_uint32(&p_manifest[iofs+16]);

				String tname=string_table[name];

//				printf("NSPACE: %i\n",nspace);
				//printf("NAME: %i (%s)\n",name,tname.utf8().get_data());
				//printf("CHECK: %x\n",check);
				uint32_t attrcount=decode_uint32(&p_manifest[iofs+20]);
				iofs+=28;
				//printf("ATTRCOUNT: %x\n",attrcount);
				for(int i=0;i<attrcount;i++) {
					uint32_t attr_nspace=decode_uint32(&p_manifest[iofs]);
					uint32_t attr_name=decode_uint32(&p_manifest[iofs+4]);
					uint32_t attr_value=decode_uint32(&p_manifest[iofs+8]);
					uint32_t attr_flags=decode_uint32(&p_manifest[iofs+12]);
					uint32_t attr_resid=decode_uint32(&p_manifest[iofs+16]);


					String value;
					if (attr_value!=0xFFFFFFFF)
						value=string_table[attr_value];
					else
						value="Res #"+itos(attr_resid);
					String attrname = string_table[attr_name];
					String nspace;
					if (attr_nspace!=0xFFFFFFFF)
						nspace=string_table[attr_nspace];
					else
						nspace="";

					printf("ATTR %i NSPACE: %i\n",i,attr_nspace);
					printf("ATTR %i NAME: %i (%s)\n",i,attr_name,attrname.utf8().get_data());
					printf("ATTR %i VALUE: %i (%s)\n",i,attr_value,value.utf8().get_data());
					printf("ATTR %i FLAGS: %x\n",i,attr_flags);
					printf("ATTR %i RESID: %x\n",i,attr_resid);

					//replace project information
					if (tname=="manifest" && attrname=="package") {

						print_line("FOUND PACKAGE");
						string_table[attr_value]=package;
					}

					//print_line("tname: "+tname);
					//print_line("nspace: "+nspace);
					//print_line("attrname: "+attrname);
					if (tname=="manifest" && /*nspace=="android" &&*/ attrname=="versionCode") {

						print_line("FOUND versioncode");
						encode_uint32(version_code,&p_manifest[iofs+16]);
					}


					if (tname=="manifest" && /*nspace=="android" &&*/ attrname=="versionName") {

						print_line("FOUND versionname");
						if (attr_value==0xFFFFFFFF) {
							WARN_PRINT("Version name in a resource, should be plaintext")
						} else
							string_table[attr_value]=version_name;
					}

					if (tname=="activity" && /*nspace=="android" &&*/ attrname=="screenOrientation") {

						print_line("FOUND screen orientation");
						if (attr_value==0xFFFFFFFF) {
							WARN_PRINT("Version name in a resource, should be plaintext")
						} else {
							string_table[attr_value]=(orientation==0?"landscape":"portrait");
						}
					}

					if (tname=="application" && /*nspace=="android" &&*/ attrname=="label") {

						print_line("FOUND application");
						if (attr_value==0xFFFFFFFF) {
							WARN_PRINT("Application name in a resource, should be plaintext.")
						} else {

							String aname = get_project_name();
							string_table[attr_value]=aname;
						}
					}
					if (tname=="activity" && /*nspace=="android" &&*/ attrname=="label") {

						print_line("FOUND activity name");
						if (attr_value==0xFFFFFFFF) {
							WARN_PRINT("Activity name in a resource, should be plaintext")
						} else {
							String aname;
							if (this->name!="") {
								aname=this->name;
							} else {
								aname = Globals::get_singleton()->get("application/name");

							}

							if (aname=="") {
								aname=_MKSTR(VERSION_NAME);
							}

							print_line("APP NAME IS..."+aname);
							string_table[attr_value]=aname;
						}
					}

					iofs+=20;
				}
Beispiel #29
0
void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest,bool p_give_internet) {


	const int CHUNK_AXML_FILE = 0x00080003;
	const int CHUNK_RESOURCEIDS = 0x00080180;
	const int CHUNK_STRINGS = 0x001C0001;
	const int CHUNK_XML_END_NAMESPACE = 0x00100101;
	const int CHUNK_XML_END_TAG = 0x00100103;
	const int CHUNK_XML_START_NAMESPACE = 0x00100100;
	const int CHUNK_XML_START_TAG = 0x00100102;
	const int CHUNK_XML_TEXT = 0x00100104;
	const int UTF8_FLAG = 0x00000100;

	Vector<String> string_table;

	uint32_t ofs=0;


	uint32_t header = decode_uint32(&p_manifest[ofs]);
	uint32_t filesize = decode_uint32(&p_manifest[ofs+4]);
	ofs+=8;

//	print_line("FILESIZE: "+itos(filesize)+" ACTUAL: "+itos(p_manifest.size()));

	uint32_t string_count;
	uint32_t styles_count;
	uint32_t string_flags;
	uint32_t string_data_offset;

	uint32_t styles_offset;
	uint32_t string_table_begins;
	uint32_t string_table_ends;
	Vector<uint8_t> stable_extra;

	while(ofs < p_manifest.size()) {

		uint32_t chunk = decode_uint32(&p_manifest[ofs]);
		uint32_t size = decode_uint32(&p_manifest[ofs+4]);


		switch(chunk) {

			case CHUNK_STRINGS: {


				int iofs=ofs+8;

				string_count=decode_uint32(&p_manifest[iofs]);
				styles_count=decode_uint32(&p_manifest[iofs+4]);
				uint32_t string_flags=decode_uint32(&p_manifest[iofs+8]);
				string_data_offset=decode_uint32(&p_manifest[iofs+12]);
				styles_offset=decode_uint32(&p_manifest[iofs+16]);
/*
				printf("string count: %i\n",string_count);
				printf("flags: %i\n",string_flags);
				printf("sdata ofs: %i\n",string_data_offset);
				printf("styles ofs: %i\n",styles_offset);
*/
				uint32_t st_offset=iofs+20;
				string_table.resize(string_count);
				uint32_t string_end=0;

				string_table_begins=st_offset;


				for(int i=0;i<string_count;i++) {

					uint32_t string_at = decode_uint32(&p_manifest[st_offset+i*4]);
					string_at+=st_offset+string_count*4;

					ERR_EXPLAIN("Unimplemented, can't read utf8 string table.");
					ERR_FAIL_COND(string_flags&UTF8_FLAG);

					if (string_flags&UTF8_FLAG) {



					} else {
						uint32_t len = decode_uint16(&p_manifest[string_at]);
						Vector<CharType> ucstring;
						ucstring.resize(len+1);
						for(int j=0;j<len;j++) {
							uint16_t c=decode_uint16(&p_manifest[string_at+2+2*j]);
							ucstring[j]=c;
						}
						string_end=MAX(string_at+2+2*len,string_end);
						ucstring[len]=0;
						string_table[i]=ucstring.ptr();
					}


//					print_line("String "+itos(i)+": "+string_table[i]);
				}

				for(int i=string_end;i<(ofs+size);i++) {
					stable_extra.push_back(p_manifest[i]);
				}

//				printf("stable extra: %i\n",int(stable_extra.size()));
				string_table_ends=ofs+size;

//				print_line("STABLE SIZE: "+itos(size)+" ACTUAL: "+itos(string_table_ends));

			} break;
			case CHUNK_XML_START_TAG: {

				int iofs=ofs+8;
				uint32_t line=decode_uint32(&p_manifest[iofs]);
				uint32_t nspace=decode_uint32(&p_manifest[iofs+8]);
				uint32_t name=decode_uint32(&p_manifest[iofs+12]);
				uint32_t check=decode_uint32(&p_manifest[iofs+16]);

				String tname=string_table[name];

//				printf("NSPACE: %i\n",nspace);
				//printf("NAME: %i (%s)\n",name,tname.utf8().get_data());
				//printf("CHECK: %x\n",check);
				uint32_t attrcount=decode_uint32(&p_manifest[iofs+20]);
				iofs+=28;
				//printf("ATTRCOUNT: %x\n",attrcount);
				for(int i=0;i<attrcount;i++) {
					uint32_t attr_nspace=decode_uint32(&p_manifest[iofs]);
					uint32_t attr_name=decode_uint32(&p_manifest[iofs+4]);
					uint32_t attr_value=decode_uint32(&p_manifest[iofs+8]);
					uint32_t attr_flags=decode_uint32(&p_manifest[iofs+12]);
					uint32_t attr_resid=decode_uint32(&p_manifest[iofs+16]);


					String value;
					if (attr_value!=0xFFFFFFFF)
						value=string_table[attr_value];
					else
						value="Res #"+itos(attr_resid);
					String attrname = string_table[attr_name];
					String nspace;
					if (attr_nspace!=0xFFFFFFFF)
						nspace=string_table[attr_nspace];
					else
						nspace="";

					printf("ATTR %i NSPACE: %i\n",i,attr_nspace);
					printf("ATTR %i NAME: %i (%s)\n",i,attr_name,attrname.utf8().get_data());
					printf("ATTR %i VALUE: %i (%s)\n",i,attr_value,value.utf8().get_data());
					printf("ATTR %i FLAGS: %x\n",i,attr_flags);
					printf("ATTR %i RESID: %x\n",i,attr_resid);

					//replace project information
					if (tname=="manifest" && attrname=="package") {

						print_line("FOUND PACKAGE");
						string_table[attr_value]=get_package_name();
					}

					//print_line("tname: "+tname);
					//print_line("nspace: "+nspace);
					//print_line("attrname: "+attrname);
					if (tname=="manifest" && /*nspace=="android" &&*/ attrname=="versionCode") {

						print_line("FOUND versioncode");
						encode_uint32(version_code,&p_manifest[iofs+16]);
					}


					if (tname=="manifest" && /*nspace=="android" &&*/ attrname=="versionName") {

						print_line("FOUND versionname");
						if (attr_value==0xFFFFFFFF) {
							WARN_PRINT("Version name in a resource, should be plaintext")
						} else
							string_table[attr_value]=version_name;
					}

					if (tname=="activity" && /*nspace=="android" &&*/ attrname=="screenOrientation") {

						encode_uint32(orientation==0?0:1,&p_manifest[iofs+16]);
						/*
						print_line("FOUND screen orientation");
						if (attr_value==0xFFFFFFFF) {
							WARN_PRINT("Version name in a resource, should be plaintext")
						} else {
							string_table[attr_value]=(orientation==0?"landscape":"portrait");
						}*/
					}

					if (tname=="uses-permission" && /*nspace=="android" &&*/ attrname=="name") {

						if (value.begins_with("godot.custom")) {

							int which = value.get_slice(".",2).to_int();
							if (which>=0 && which<MAX_USER_PERMISSIONS && user_perms[which].strip_edges()!="") {

								string_table[attr_value]=user_perms[which].strip_edges();
							}

						} else if (value.begins_with("godot.")) {
							String perm = value.get_slice(".",1);
							print_line("PERM: "+perm+" HAS: "+itos(perms.has(perm)));

							if (perms.has(perm) || (p_give_internet && perm=="INTERNET")) {

								string_table[attr_value]="android.permission."+perm;
							}

						}
					}

					if (tname=="supports-screens" ) {

						if (attrname=="smallScreens") {

							encode_uint32(screen_support[SCREEN_SMALL]?0xFFFFFFFF:0,&p_manifest[iofs+16]);

						} else if (attrname=="normalScreens") {

							encode_uint32(screen_support[SCREEN_NORMAL]?0xFFFFFFFF:0,&p_manifest[iofs+16]);

						} else if (attrname=="largeScreens") {

							encode_uint32(screen_support[SCREEN_LARGE]?0xFFFFFFFF:0,&p_manifest[iofs+16]);

						} else if (attrname=="xlargeScreens") {

							encode_uint32(screen_support[SCREEN_XLARGE]?0xFFFFFFFF:0,&p_manifest[iofs+16]);

						}
					}


					iofs+=20;
				}

			} break;
		}
		printf("chunk %x: size: %d\n",chunk,size);

		ofs+=size;
	}
Beispiel #30
0
void EditorExportPlatformAndroid::_fix_resources(Vector<uint8_t>& p_manifest) {


	const int UTF8_FLAG = 0x00000100;
	print_line("*******************GORRRGLE***********************");

	uint32_t header = decode_uint32(&p_manifest[0]);
	uint32_t filesize = decode_uint32(&p_manifest[4]);
	uint32_t string_block_len = decode_uint32(&p_manifest[16]);
	uint32_t string_count = decode_uint32(&p_manifest[20]);
	uint32_t string_flags = decode_uint32(&p_manifest[28]);
	const uint32_t string_table_begins = 40;

	Vector<String> string_table;

	printf("stirng block len: %i\n",string_block_len);
	printf("stirng count: %i\n",string_count);
	printf("flags: %x\n",string_flags);

	for(int i=0;i<string_count;i++) {

		uint32_t offset = decode_uint32(&p_manifest[string_table_begins+i*4]);
		offset+=string_table_begins+string_count*4;

		String str = _parse_string(&p_manifest[offset],string_flags&UTF8_FLAG);

		if (str.begins_with("godot-project-name")) {


			if (str=="godot-project-name") {
				//project name
				str = get_project_name();

			} else {

				String lang = str.substr(str.find_last("-")+1,str.length()).replace("-","_");
				String prop = "application/name_"+lang;
				if (Globals::get_singleton()->has(prop)) {
					str = Globals::get_singleton()->get(prop);
				} else {
					str = get_project_name();
				}
			}
		}

		string_table.push_back(str);

	}

	//write a new string table, but use 16 bits
	Vector<uint8_t> ret;
	ret.resize(string_table_begins+string_table.size()*4);

	for(int i=0;i<string_table_begins;i++) {

		ret[i]=p_manifest[i];
	}

	int ofs=0;
	for(int i=0;i<string_table.size();i++) {

		encode_uint32(ofs,&ret[string_table_begins+i*4]);
		ofs+=string_table[i].length()*2+2+2;
	}

	ret.resize(ret.size()+ofs);
	uint8_t *chars=&ret[ret.size()-ofs];
	for(int i=0;i<string_table.size();i++) {

		String s = string_table[i];
		encode_uint16(s.length(),chars);
		chars+=2;
		for(int j=0;j<s.length();j++) {
			encode_uint16(s[j],chars);
			chars+=2;
		}
		encode_uint16(0,chars);
		chars+=2;
	}

	//pad
	while(ret.size()%4)
		ret.push_back(0);

	//change flags to not use utf8
	encode_uint32(string_flags&~0x100,&ret[28]);
	//change length
	encode_uint32(ret.size()-12,&ret[16]);
	//append the rest...
	int rest_from = 12+string_block_len;
	int rest_to = ret.size();
	int rest_len = (p_manifest.size() - rest_from);
	ret.resize(ret.size() + (p_manifest.size() - rest_from) );
	for(int i=0;i<rest_len;i++) {
		ret[rest_to+i]=p_manifest[rest_from+i];
	}
	//finally update the size
	encode_uint32(ret.size(),&ret[4]);


	p_manifest=ret;
	printf("end\n");
}